MySql5.7 本地变量区域和解决方法
本地变量的区域是其所定义的BEGIN … END块中。本地变量可以在其嵌套的内层被索引到,除非内层也定义了同名的变量。
因为本地变量仅在存储的程序执行其间存在,不能在程序的预处理声明阶段索引到它们。预处理声明区域是当前会话,而不是被存储的程序,所以这个声明能在程序结束后被执行,在这个阶段的变量并不在其作用域。(Prepared statement scope is the current session, not the stored program, so the statement could be executed after the program ends, at which point the variables would no longer be in scope. )例如,SELECT … INTO local_var不能用于预处理阶段。这个限制同样用于存储过程和函数的参数。(See Section 13.5.1, “PREPARE Syntax”.)
本地变量不能同名。如果一个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;
MYSQL在SELECT语句中解释xname作为变量,而不是列名。因此在调用sp1()这个过程时newname返回’bob’,而不是table1.xname列。
类似的,在游标定义中(包含SELECT指向xname声明的过程)中。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;