Documentation Home
MySQL 8.3 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 40.8Mb
PDF (A4) - 40.9Mb
Man Pages (TGZ) - 294.0Kb
Man Pages (Zip) - 409.0Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb
Excerpts from this Manual

MySQL 8.3 Reference Manual  /  ...  /  Local Variable Scope and Resolution

15.6.4.2 局部变量作用域和解析

局部变量的作用域是声明它的 BEGIN ... END 块。变量可以在声明块中的嵌套块中引用,除非这些块声明了同名的变量。

因为局部变量仅在存储程序执行期间处于作用域中,因此不能在存储程序中创建的预备语句中引用它们。预备语句的作用域是当前会话,而不是存储程序,因此语句可能在程序结束后执行,此时变量将不再处于作用域中。例如,SELECT ... INTO local_var 不能用作预备语句。这也适用于存储过程和函数参数。见 第 15.5.1 节,“PREPARE 语句”

局部变量不应该与表列同名。如果 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 将 xnameSELECT 语句中解释为对 xname 变量 的引用,而不是 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;

另见 第 27.8 节,“存储程序限制”