GOTO语句

GOTO语句可以实现从GOTO位置到目标语句的无条件跳转。GOTO语句会改变原本的执行逻辑,因此应该慎重使用,或者也可以使用EXCEPTION处理特殊场景。当执行GOTO语句时,目标Label必须是唯一的。

语法

label declaration ::=

GOTO语句 - 图1

goto statement ::=

GOTO语句 - 图2

示例

1. openGauss=# CREATE OR REPLACE PROCEDURE GOTO_test()
2. AS
3. DECLARE
4. v1  int;
5. BEGIN
6. v1  := 0;
7. LOOP
8. EXIT WHEN v1 > 100;
9. v1 := v1 + 2;
10. if v1 > 25 THEN
11. GOTO pos1;
12. END IF;
13. END LOOP;
14. <<pos1>>
15. v1 := v1 + 10;
16. raise info 'v1 is %. ', v1;
17. END;
18. /

20. call GOTO_test();

限制场景

GOTO使用有以下限制场景

  • 不支持有多个相同的GOTO labels目标场景,无论是否在同一个block中。

1. BEGIN 2. GOTO pos1; 3. <<pos1>> 4. SELECT * FROM ... 5. <<pos1>> 6. UPDATE t1 SET ... 7. END; - 不支持GOTO跳转到IF语句,CASE语句,LOOP语句中。

1. BEGIN 2. GOTO pos1; 3. IF valid THEN 4. <<pos1>> 5. SELECT * FROM ... 6. END IF; 7. END; - 不支持GOTO语句从一个IF子句跳转到另一个IF子句,或从一个CASE语句的WHEN子句跳转到另一个WHEN子句。

1. BEGIN 2. IF valid THEN 3. GOTO pos1; 4. SELECT * FROM ... 5. ELSE 6. <<pos1>> 7. UPDATE t1 SET ... 8. END IF; 9. END; - 不支持从外部块跳转到内部的BEGIN-END块。

1. BEGIN 2. GOTO pos1; 3. BEGIN 4. <<pos1>> 5. UPDATE t1 SET ... 6. END; 7. END; - 不支持从异常处理部分跳转到当前的BEGIN-END块。但可以跳转到上层BEGIN-END块。

1. BEGIN 2. <<pos1>> 3. UPDATE t1 SET ... 4. EXCEPTION 5. WHEN condition THEN 6. GOTO pos1; 7. END; - 如果从GOTO到一个不包含执行语句的位置,需要添加NULL语句。

1. DECLARE 2. done BOOLEAN; 3. BEGIN 4. FOR i IN 1..50 LOOP 5. IF done THEN 6. GOTO end_loop; 7. END IF; 8. <<end_loop>> -- not allowed unless an executable statement follows 9. NULL; -- add NULL statement to avoid error 10. END LOOP; -- raises an error without the previous NULL 11. END; 12. /