13.6.4.2 Область действия и разрешение локальных переменных
Область действия локальной переменной — это блок BEGIN ...
END, внутри которого она объявлена. К переменной можно обратиться в вложенных блоках, за исключением блоков, которые объявляют переменную с тем же именем.
Поскольку локальные переменные существуют только во время выполнения программы, ссылки на них запрещены в подготовленных операторах, созданных внутри хранимой программы. Область действия подготовленного оператора — текущая сессия, а не хранимая программа, поэтому оператор может быть выполнен после завершения программы, в этот момент переменные будут недоступны. Например, SELECT ... INTO
не может использоваться как подготовленный оператор. Это ограничение также применяется к параметрам хранимых процедур и функций. См. Раздел 13.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;
См. также Раздел 23.8, «Ограничения хранимых программ».
© 2025 Oracle
Licensed under the GPLv2 License.