MySQL 9.0 发行说明
局部变量的作用域是声明它的 BEGIN ... END
块。在声明块内部嵌套的块中可以引用该变量,除了那些声明了相同名称变量的块。
由于局部变量只在存储程序执行期间有效,因此在存储程序中创建的预处理语句中不允许引用它们。预处理语句的作用域是当前会话,而不是存储程序,因此该语句可以在程序结束之后执行,此时变量将不再有效。例如,SELECT ... INTO
不能用作预处理语句。此限制也适用于存储过程和函数参数。请参见 第 15.5.1 节,“PREPARE 语句”。local_var
局部变量不应该与表列具有相同的名称。如果 SQL 语句(例如 SELECT ... INTO
语句)包含对具有相同名称的列和声明的局部变量的引用,MySQL 当前会将该引用解释为变量的名称。考虑以下过程定义
CREATE PROCEDURE sp1 (x VARCHAR(5))
BEGIN
DECLARE xname VARCHAR(5) DEFAULT 'bob';
DECLARE newname VARCHAR(5);
DECLARE xid INT;
SELECT xname, id INTO newname, xid
FROM table1 WHERE xname = xname;
SELECT newname;
END;
在 SELECT
语句中,MySQL 将 xname
解释为对 xname
变量 的引用,而不是对 xname
列 的引用。因此,当调用过程 sp1()
时,newname
变量将返回值 'bob'
,无论 table1.xname
列的值是什么。
类似地,以下过程中的游标定义包含一个引用 xname
的 SELECT
语句。MySQL 将其解释为对该名称的变量的引用,而不是列引用。
CREATE PROCEDURE sp2 (x VARCHAR(5))
BEGIN
DECLARE xname VARCHAR(5) DEFAULT 'bob';
DECLARE newname VARCHAR(5);
DECLARE xid INT;
DECLARE done TINYINT DEFAULT 0;
DECLARE cur1 CURSOR FOR SELECT xname, id FROM table1;
DECLARE CONTINUE HANDLER FOR NOT FOUND SET done = 1;
OPEN cur1;
read_loop: LOOP
FETCH FROM cur1 INTO newname, xid;
IF done THEN LEAVE read_loop; END IF;
SELECT newname;
END LOOP;
CLOSE cur1;
END;
另请参阅 第 27.9 节,“存储过程限制”。