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

时间:2018-10-08 23:09:19

标签: mysql sql stored-procedures

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

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

我的理解是,我可以通过几种方式对其进行设置,包括“ SET”和“ SELECT INTO”。

SET产生了我期望的结果,它设置了局部变量,在这种情况下将其设置为NULL,从而触发退出处理程序。

SELECT INTO无法产生我期望的结果。似乎没有将其设置为NULL,因此从不通知退出处理程序。

真正让我感到奇怪的是,示例2中甚至没有触发最后一个SIGNAL SQLSTATE '45000'

我想念什么?

谢谢

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 ;

1 个答案:

答案 0 :(得分:2)

考虑以下语句:

SELECT id INTO v_var
FROM our_table
WHERE id = p_id;

这遍历our_table。当找到匹配项时,将调用SELECT子句的 then 并将值放在变量中。唉。没有匹配项,没有调用SELECT,也没有分配。

SET是另外一个故事:

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

(请注意,:=不需要SET。)这是使用标量子查询。标量子查询始终返回一个值。如果子查询返回一行,则为该值。如果子查询不返回任何行,则值为NULL。因此,在这种情况下分配了NULL

换句话说,根本没有分配与NULL分配相同。