MySQL 8.4 發行說明
區域變數的範圍是宣告它的 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 將 SELECT
陳述式中的 xname
解釋為對 xname
變數 的引用,而不是對 xname
欄位 的引用。因此,當呼叫程序 sp1()
時,newname
變數會傳回值 'bob'
,而不管 table1.xname
欄位的值為何。
同樣地,以下程序中的游標定義包含一個引用 xname
的 SELECT
陳述式。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 節,「儲存程式的限制」。