GaussDB-GOTO语句

72 阅读2分钟

GaussDB-GOTO语句

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

语法

label declaration ::=语句如图1所示。

图1 label declaration ::

goto statement ::=语句如图2所示。

图2 goto statement ::

示例

| ``` gaussdb=# CREATE OR REPLACE PROCEDURE GOTO_test() AS DECLARE v1 int; BEGIN v1 := 0; LOOP EXIT WHEN v1 > 100; v1 := v1 + 2; if v1 > 25 THEN GOTO pos1; END IF; END LOOP; <> v1 := v1 + 10; raise info 'v1 is %. ', v1; END; / CREATE PROCEDURE gaussdb=# call GOTO_test(); INFO: v1 is 36. goto_test ----------- (1 row)

| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |

#### 限制场景

GOTO使用有以下限制场景

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

    | ```
    BEGIN   GOTO pos1;    <<pos1>>   SELECT * FROM ...   <<pos1>>   UPDATE t1 SET ... END; 
    ``` |
    | ----------------------------------------------------------------------------------------------- |

<!---->

-   不支持GOTO跳转到IF语句,CASE语句,LOOP语句中。

    | ```
    BEGIN    GOTO pos1;     IF valid THEN      <<pos1>>      SELECT * FROM ...    END IF;  END; 
    ``` |
    | ---------------------------------------------------------------------------------------------------- |

<!---->

-   不支持GOTO语句从一个IF子句跳转到另一个IF子句,或从一个CASE语句的WHEN子句跳转到另一个WHEN子句。

    | ```
    BEGIN     IF valid THEN      GOTO pos1;      SELECT * FROM ...    ELSE      <<pos1>>      UPDATE t1 SET ...    END IF;  END; 
    ``` |
    | ------------------------------------------------------------------------------------------------------------------------------------- |

<!---->

-   不支持从外部块跳转到内部的BEGIN-END块。

    | ```
    BEGIN    GOTO pos1;      BEGIN      <<pos1>>      UPDATE t1 SET ...    END;  END; 
    ``` |
    | ------------------------------------------------------------------------------------------ |

<!---->

-   不支持从异常处理部分跳转到当前的BEGIN-END块。但可以跳转到上层BEGIN-END块。

    | ```
    BEGIN    <<pos1>>    UPDATE t1 SET ...    EXCEPTION      WHEN condition THEN         GOTO pos1;  END; 
    ``` |
    | -------------------------------------------------------------------------------------------------------------- |

<!---->

-   如果从GOTO到一个不包含执行语句的位置,需要添加NULL语句。

    | ```
    DECLARE    done  BOOLEAN; BEGIN    FOR i IN 1..50 LOOP       IF done THEN          GOTO end_loop;       END IF;       <<end_loop>>  -- 除非后面有可执行语句,否则不允许GOTO到这里       NULL; -- 这里添加NULL语句避免错误    END LOOP;  -- 如果没有上一句NULL会报错 END; / 
    ``` |
    | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |

更多详情请参考GaussDB 文档中心:<https://doc.hcs.huawei.com/db/zh-cn/gaussdbqlh/24.1.30/productdesc/qlh_03_0001.html>