MySQL,存储过程,差异设置局部变量

标签 mysql sql stored-procedures

我在 MySQL (5.7.22) 中有一个存储过程

我有一个声明的局部变量。

我的理解是我可以通过多种方式设置它,包括“SET”和“SELECT INTO”。

SET产生我期望的结果,它设置局部变量,在本例中设置为 NULL,这会触发退出处理程序。

SELECT INTO没有产生我期望的结果。它似乎没有将其设置为 NULL,因此退出处理程序永远不会发出信号。

对我来说真正奇怪的是最后的 SIGNAL SQLSTATE '45000'示例 2 中甚至没有触发。

我错过了什么?

谢谢

DELIMITER $$
CREATE PROCEDURE `test_proc`(IN p_id INT)
BEGIN
  DECLARE v_var INT DEFAULT NULL;

  DECLARE EXIT HANDLER FOR SQLEXCEPTION, SQLWARNING
  BEGIN
   RESIGNAL;
  END;

  /* Example 1 - works as expected */
  SET v_var := (SELECT `id` FROM our_table WHERE `id` = p_id);

  /* this is triggered */
  IF(v_var IS NULL) THEN
    SIGNAL SQLSTATE '45000'
      SET MESSAGE_TEXT = 'Not found';
  END IF;


   -- comment out above to run example 2

  /* Example 2 - Does not work as expected */
  SELECT `id` INTO v_var FROM our_table WHERE `id`=p_id;

  /* this is not triggered */
  IF(v_var IS NULL) THEN
    SIGNAL SQLSTATE '45000'
      SET MESSAGE_TEXT = 'Not found';
  END IF;

  /* in fact - this is not triggered either... */
  SIGNAL SQLSTATE '45000'
    SET MESSAGE_TEXT = 'Not found';


END$$
DELIMITER ;

最佳答案

考虑这个陈述:

SELECT id INTO v_var
FROM our_table
WHERE id = p_id;

这会循环遍历our_table。当找到匹配项时,then 将调用 SELECT 子句并将值放入变量中。唉。没有匹配,没有调用SELECT——也没有赋值。

SET 是一个不同的故事:

SET v_var = (SELECT `id` FROM our_table WHERE `id` = p_id);

(请注意,SET 不需要 :=。)这使用了标量子查询。标量子查询始终返回一个值。如果子查询返回一行,那么这就是值。如果子查询没有返回任何行,则值为NULL。因此,在本例中分配了 NULL

换句话说,根本不赋值NULL 的赋值不同。

关于MySQL,存储过程,差异设置局部变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52711201/

相关文章:

sql - 如何根据 "many"中的某些标准对基于一对多关联的查询结果进行分组?

Azure SQL 数据库 : Can I share stored procedures between master DB and all DB's in the server?

sql - Postgresql:有没有办法像 Microsoft SQL Server 那样从存储过程返回表数据和输出参数

php - MySQL查询在PHP中返回null,但在终端中很好

php - 联合表的语法错误

sql - 在 PostgreSQL 中获取表注释列表

oracle - PL/SQL 嵌套过程异常处理

mysql - SQL,避免使用内部选择

mysql - MySQL 中何时使用单引号、双引号和反引号

php - 如何合并数据库中的数组数据