Documentation Home
MySQL 8.4 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 39.8Mb
PDF (A4) - 39.9Mb
Man Pages (TGZ) - 257.9Kb
Man Pages (Zip) - 364.9Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


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

15.6.4.2 局部变量范围和解析

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

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

局部变量不应该与表列同名。如果 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 作为对 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;

请参见Section 27.8,“存储程序限制”。