15.6.4.2 Область действия и разрешение локальных переменных
Область действия локальной переменной — это 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;
MySQL интерпретирует xname в SELECT операторе как ссылку на 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, «Ограничения хранимых программ».
© 2025 Oracle
Licensed under the GPLv2 License.