#GOTO Statement

GOTO Statement为顺序控制语句,其语法形式为:

<<label_name>> statement

...

GOTO label_name;

其中,<<>>用于为其后面的statement定义一个标签(Label),label_name为定义的标签的名字。

# <<label_name>>

用于为其后面的statement定义一个标签(Label),label_name为定义的标签的名称。

在同一个PL/SQL过程体里,标签的名称不能重复,否则报错。

标签可以位于过程体的任何位置,但如下位置除外:

  • END IF前面
  • END LOOP前面
  • END CASE前面
  • END前面
  • CASE Statement中的WHEN前面
  • EXCEPTION前面
  • 过程体结束符'/'前面

当为如下statement定义标签时:

  • 以DECLARE开头的程序块,此时除了用于表示跳转位置外,与其连续使用的label_name还可作为这个程序块的名称来使用,例如通过label_name.variable_name,可以访问在这个程序块里声明的变量。
  • 以FOR开头的循环语句,此时除了用于表示跳转位置外,label_name还可作为这个FOR语句的名称来使用,例如通过label_name.variable_name,可以访问在这个FOR语句里声明的变量。

# GOTO label_name

GOTO label_name表示跳转到label_name标签所指向的statement,并从此statement开始往下执行。

当GOTO label_name位于某个PL/SQL语句的子句里面时,只能向外层跳转,而不能向同一层或更里层跳转。

示例

--label\_name未与DECLARE开头的程序块连续使用
CREATE OR REPLACE PROCEDURE ya_proc(a VARCHAR, b VARCHAR) AS
BEGIN
    <<label1>>
    DBMS_OUTPUT.PUT_LINE(a);
    <<label2>>
        DECLARE
        a INT:=3;
        b INT:=3;
        BEGIN
            SELECT * INTO label1.a FROM dual;
            SELECT * INTO label2.b FROM dual;
        DBMS_OUTPUT.PUT_LINE('a+1 = '|| a);
        DBMS_OUTPUT.PUT_LINE('b+1 = '|| b);
        END;
    END;
/
YAS-04253 PL/SQL compiling errors:
[10:27] YAS-04243 invalid identifier "LABEL1"."A"

--label\_name与DECLARE开头的程序块连续使用
CREATE OR REPLACE PROCEDURE ya_proc(a VARCHAR, b VARCHAR) AS
BEGIN
    <<label1>>
    <<label2>>
        DECLARE
        a INT:=3;
        b INT:=3;
        BEGIN
            SELECT * INTO label1.a FROM dual;
            SELECT * INTO label2.b FROM dual;
        DBMS_OUTPUT.PUT_LINE('a+1 = '|| a);
        DBMS_OUTPUT.PUT_LINE('b+1 = '|| b);
        END;
    END;
/

CREATE OR REPLACE PROCEDURE ya_proc() IS
BEGIN
    CASE WHEN true THEN
    <<a>>
        DBMS_OUTPUT.PUT_LINE('hello');
    WHEN false THEN
        DBMS_OUTPUT.PUT_LINE('world');
    END CASE;
    GOTO a;
END;
/
YAS-04253 PL/SQL compiling errors:
[9:1] YAS-05223 invalid goto statement cannot jump to to label A
 
CREATE OR REPLACE PROCEDURE ya_proc() IS
BEGIN
    FOR i IN 1..3 LOOP
        DBMS_OUTPUT.PUT_LINE(i);
        GOTO a;
    END LOOP;
    <<a>>
    CASE WHEN true THEN
        DBMS_OUTPUT.PUT_LINE('hello');
    WHEN false THEN
        DBMS_OUTPUT.PUT_LINE('world');
    END CASE;
END;
/
  
exec ya_proc; 
  
--result
1
hello
pdf-btn 下载文档
copy-btn 复制链接