MySQL 9.0 發行說明
區域變數的範圍是宣告它的 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()
時,無論 table1.xname
欄位的值為何,newname
變數都會傳回值 'bob'
。
同樣地,以下程序中的游標定義包含一個 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.9 節「儲存程式的限制」。