#### 13.6.4.2 局部变量范围和解析

局部变量的作用域是[`开始...结束`](begin-end.html)声明它的块。该变量可以在嵌套在声明块中的块中引用，除了那些声明具有相同名称的变量的块。

因为局部变量仅在存储程序执行期间才在作用域内，所以在存储程序中创建的准备好的语句中不允许引用它们。准备好的语句作用域是当前会话，而不是存储的程序，因此该语句可以在程序结束后执行，此时变量将不再在作用域内。例如，`选择 ... 进入 *`local_var`*`不能用作准备好的语句。此限制也适用于存储过程和函数参数。看[第 13.5.1 节，“准备声明”](prepare.html).

局部变量不应与表列同名。如果一条 SQL 语句，例如[`选择...进入`](select.html)语句，包含对列的引用和同名声明的局部变量，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 解释`xname`在里面[`选择`](select.html)声明作为参考`xname` *多变的*而不是`xname` *柱子*.因此，当程序`sp1()`被称为`新名字`变量返回值`“鲍勃”`不管的价值`table1.xname`柱子。

同样，以下过程中的游标定义包含一个[`选择`](select.html)引用的语句`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;
```

也可以看看[第 25.8 节，“对存储程序的限制”](stored-program-restrictions.html).
