Spec-Zone .ru
спецификации, руководства, описания, API

13.6.4.2. Контекст Локальной переменной и Разрешение

Контекст локальной переменной BEGIN ... END блок, в пределах которого это объявляется. Переменная может быть упомянута в блоках, вложенных в пределах блока объявления, кроме тех блоков, которые объявляют переменную с тем же самым именем.

Поскольку локальные переменные находятся в контексте только во время сохраненного выполнения программы, ссылки на них не разрешаются в готовых операторах, создаваемых в пределах сохраненной программы. Готовый контекст оператора является текущим сеансом, не сохраненной программой, таким образом, оператор мог быть выполнен после концов программы, в которой точке переменные больше не будут в контексте. Например, SELECT ... INTO local_var не может использоваться в качестве готового оператора. Это ограничение также применяется к хранимой процедуре и параметрам функции. См. Раздел 13.5.1,"PREPARE Синтаксис".

У локальной переменной не должно быть того же самого имени как столбец таблицы. Если SQL-оператор, такой как a 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 столбец.

Точно так же определение курсора в следующей процедуре содержит a 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;

См. также Раздел D.1, "Ограничения на Сохраненные Программы".