【问题标题】:Oracle PL/SQL - Exit begin end block if condition is not metOracle PL/SQL - 如果不满足条件,则退出开始结束块
【发布时间】:2020-11-21 09:03:03
【问题描述】:

如果不满足条件,是否可以退出/跳过 begin end 块?

例子:

DECLARE
    my_var BOOLEAN := TRUE;

BEGIN
    IF my_var THEN
        EXIT_BEGIN_END_HERE;  -- Exits the block but continue execution after it!
    END IF;

    -- Other stuff happens here. Won't be executed if IF above is true
    INSERT INTO asdf
    VALUES ('asdf', 'asdf');
END;

-- Other stuff happens here

【问题讨论】:

    标签: oracle if-statement plsql skip


    【解决方案1】:

    使用带有标签的GOTO

    BEGIN
      DECLARE
        my_var BOOLEAN := TRUE;
      BEGIN
        IF my_var THEN
          GOTO skip_insert;
        END IF;
    
        -- Other stuff happens here. Won't be executed if IF above is true
        DBMS_OUTPUT.PUT_LINE( 'This should be skipped' );
      END;
      <<skip_insert>>
        DBMS_OUTPUT.PUT_LINE( 'Continue from here.' );
    END;
    /
    

    或者使用IF ... THEN ... ELSE ... END IF:

    DECLARE
      my_var BOOLEAN := TRUE;
    BEGIN
      IF my_var THEN
        NULL
      ELSE
        -- Other stuff happens here. Won't be executed if IF above is true
        DBMS_OUTPUT.PUT_LINE( 'This should be skipped' );
      END IF;
    
      DBMS_OUTPUT.PUT_LINE( 'Continue from here.' );
    END;
    /
    

    这两个输出:

    Continue from here.
    

    db小提琴here

    【讨论】:

      【解决方案2】:

      我认为以下是一个更好的示例(和解决方案),可以说明您要实现的目标。

      DECLARE
          my_var BOOLEAN := TRUE;
      BEGIN
          BEGIN
              IF my_var THEN
                  RAISE PROGRAM_ERROR;
              END IF;
              -- Other stuff happens here. Won't be executed if IF above is true
              DBMS_OUTPUT.PUT_LINE('Not here!');
          EXCEPTION
              WHEN OTHERS THEN
                  NULL;
          END;
          -- Other stuff happens here
          DBMS_OUTPUT.PUT_LINE('Continuing.');
      END;
      

      您只想退出内部 BEGIN-END,对吗?所以你可以使用RAISE 语句。
      如果你运行上面的代码,它会显示Continuing.

      【讨论】:

      • 您应该只捕获您提出的特定异常。
      • 引发异常是为了发生错误;这会留下不好的代码气味,因为 OP 的代码中没有发生任何不好的事情,这是滥用异常来转移程序的流程。是的,它会起作用,但如果我正在执行代码审查,我会反对使用此方法(特别是如果您正在捕获 OTHERS 而不是捕获用户定义的异常)。
      【解决方案3】:

      如果想从最外层退出,可以使用RETURN

      DECLARE
          my_var BOOLEAN := TRUE;
      
      BEGIN
          IF my_var THEN
              RETURN;  -- Exits the block but continue execution after it!
          END IF;
      
          -- Other stuff happens here. Won't be executed if IF above is true
          INSERT INTO asdf
          VALUES ('asdf', 'asdf');
      END;
      
      -- Other stuff happens here
      

      请注意,正如@MT0 所指出的,由于它从最外面的块退出,因此不会执行下面的INSERT INTO asdf

      DECLARE
          my_var BOOLEAN := TRUE;
      
      BEGIN
          BEGIN
              IF my_var THEN
                  RETURN;  -- Exits the outermost block but continue execution after it!
              END IF;
      
              INSERT INTO qwerty
              VALUES ('qwerty', 'qwerty');
          END;
      
          -- Other stuff happens here. Won't be executed if IF above is true
          INSERT INTO asdf
          VALUES ('asdf', 'asdf');
      END;
      
      -- Other stuff happens here
      

      RETURN也可以在程序内部使用。

      查看类似问题:Abort a PL/SQL program

      【讨论】:

      • 这不会从当前嵌套的 PL/SQL 块之后继续执行;它终止了最外面的块db<>fiddle
      • @MT0 谢谢。我会用这些信息更新答案!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-23
      • 1970-01-01
      • 2014-10-05
      • 2021-08-22
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多