我在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 ;
答案 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
的分配相同。