CREATE PROCEDURE p10 ()
BEGIN
DECLARE a, b INT DEFAULT 5; -- 宣告並初始化
INSERT INTO t VALUES (a);
SELECT s1 * a FROM t WHERE s1 >= b;
END;
CREATE PROCEDURE p11 ()
BEGIN
DECLARE x1 CHAR(5) DEFAULT 'outer';
BEGIN
DECLARE x1 CHAR(5) DEFAULT 'inner';
SELECT x1; -- inner
END;
SELECT x1; -- outer
END;
CREATE PROCEDURE p12 (IN p1 INT)
BEGIN
DECLARE v1 INT;
SET v1 = p1 + 1;
IF v1 = 0 THEN INSERT INTO t VALUES (17); END IF;
IF p1 = 0 THEN UPDATE t SET s1 = s1 + 1;
ELSE UPDATE t SET s1 = s1 + 2; END IF;
END;
CREATE PROCEDURE p13 (IN p1 INT)
BEGIN
DECLARE v1 INT;
SET v1 = p1 + 1;
CASE v1
WHEN 0 THEN INSERT INTO t VALUES (17);
WHEN 1 THEN INSERT INTO t VALUES (18);
ELSE INSERT INTO t VALUES (19);
END CASE;
END;
呼叫 `CALL p13(NULL)` 時 `v1=NULL`,走 ELSE 分支插入 19。
| 循環 | 檢查時機 | 適用場景 |
|---|---|---|
| WHILE | 前測試 | 可能零次執行 |
| REPEAT | 後測試 | 至少執行一次 |
| LOOP | 無內建條件 | 配合 LEAVE/ITERATE 完全控制 |
CREATE PROCEDURE p14 ()
BEGIN
DECLARE v INT DEFAULT 0;
WHILE v < 5 DO
INSERT INTO t VALUES (v);
SET v = v + 1;
END WHILE;
END;
CREATE PROCEDURE p15 ()
BEGIN
DECLARE v INT DEFAULT 0;
REPEAT
INSERT INTO t VALUES (v);
SET v = v + 1;
UNTIL v >= 5
END REPEAT;
END;
CREATE PROCEDURE p16 ()
BEGIN
DECLARE v INT DEFAULT 0;
loop_label: LOOP
INSERT INTO t VALUES (v);
SET v = v + 1;
IF v >= 5 THEN LEAVE loop_label; END IF;
END LOOP;
END;
label_1: BEGIN
label_2: BEGIN
label_3: BEGIN
IF p = 'a' THEN LEAVE label_1; -- 直接跳出最外層
ELSEIF p = 'b' THEN LEAVE label_2;
ELSE LEAVE label_3; END IF;
END label_3;
END label_2;
END label_1;
CREATE PROCEDURE p20 ()
BEGIN
DECLARE v INT DEFAULT 0;
loop_label: LOOP
IF v = 3 THEN SET v = v + 1; ITERATE loop_label; END IF;
INSERT INTO t VALUES (v);
SET v = v + 1;
IF v >= 5 THEN LEAVE loop_label; END IF;
END LOOP;
END;
結果插入 0,1,2,4 (跳過 3)。
語法:`LABEL label_name; ... GOTO label_name;` 非標準 SQL,未來可能移除,僅為相容保留。
CREATE PROCEDURE p21 (IN p1 INT, OUT p2 INT)
LANGUAGE SQL DETERMINISTIC SQL SECURITY INVOKER
BEGIN
DECLARE v INT;
label_goto: LABEL goto_label;
start_label: LOOP
IF v = v THEN LEAVE start_label; ELSE ITERATE start_label; END IF;
END LOOP start_label;
REPEAT WHILE 1=0 DO BEGIN END; END WHILE UNTIL v=v END REPEAT;
GOTO goto_label;
END;
語法合法但含無窮迴圈,僅供語法參考。