【问题标题】:Why is code in PLSQL not executing after "exception" part?为什么 PLSQL 中的代码在“异常”部分之后没有执行?
【发布时间】:2020-12-26 16:37:28
【问题描述】:

所以我犯了一个错误,我没有在嵌套的 begin-end 块中立即执行,所以我的代码不起作用。所以基本上我有

begin
 execute immediate 'select * from sales';
 exception when others then null;
 dbms_output.put_line(123);
end;

Dbms_output 没有打印“123”,我发现我需要在 begin-end 中立即执行。我想确定,所以我的问题是为什么即使没有引发异常,代码也不会在异常部分之后执行?

【问题讨论】:

  • 无法复制,因为抛出异常。 db<>fiddle
  • 我目前在DataGrip工作,这是一张照片example@MT0
  • 在运行 PL/SQL 匿名块之前尝试运行 SET SERVEROUTPUT ON; 以显示控制台输出。
  • 您的 dbms_output 是异常的一部分,它将在不执行任何操作的“null”部分之后执行。你有一个叫做销售的表吗?如果是,那么您的立即执行不会引发错误,因此 dbms_output 不会被执行。
  • @wemfried,不,如果没有 into 子句,它不会引发异常。注释 dbfiddle 中的异常行,然后尝试(将 sales 替换为 dual 后)

标签: oracle plsql plsqldeveloper oracle18c


【解决方案1】:

为什么即使没有引发异常,代码也没有在异常部分之后执行?

原因很简单——问题中的dbms_output.put_line不在“异常部分之后”

正确缩进的代码相当于:

begin
    execute immediate 'select * from dual';
exception when others then 
    null;
    dbms_output.put_line(123);
end;
/

异常块是EXCEPTIONSEND; 之间的所有内容,如果发生异常将被执行。

【讨论】:

    【解决方案2】:

    这里有几件事在起作用 - 解析和执行。

    如果表不存在,则无法解析该语句,因此我们会立即得到一个异常。

    SQL> begin
      2     execute immediate 'select * from xxxx';
      3  end;
      4  /
    begin
    *
    ERROR at line 1:
    ORA-00942: table or view does not exist
    ORA-06512: at line 2
    

    但是,如果表确实存在,那么解析就可以了。因为您从未指定过我们所做的所有的INTO。我们从来不需要执行和开始获取阶段,因此没有发生错误。一个容易看出我们从未执行过该语句的方法是使用类似

    SQL> begin
      2     execute immediate 'select 1/count(*) from dual where 1=2';
      3  end;
      4  /
    
    PL/SQL procedure successfully completed.
    

    如果我们已经执行,那么我们预计会出现除以零的错误。当我们看到 INTO 时,我们需要获取(这将需要执行)。

    【讨论】:

    • 我明白了,但上面的代码只是示例,在我的实际代码中我已经进入。请查看我上面在源问题 cmets 中的最后一条评论,我在其中解释了我发现非常奇怪的事情。至少对我来说。
    • 你唯一的工作与否的证据是看到 dbms_output.put_line 的输出。但这是您必须了解的基本原理。 dbms_output.put_line 写入控制台,它写入内部缓冲区。然后在程序完成后,调用客户端可以(或不可以)选择如何处理该缓冲区。有些客户总是忽略它。 当且仅当您已发出“set serverout on”命令时,sqlplus 才会选择处理和显示它。
    • @EdStevens 我明白了,你是对的。但是,当引发异常而不是未引发异常时,相同的代码如何工作?那么当引发异常时,DataGrip 显示内部缓冲区,而当未引发异常时,它会忽略它?
    猜你喜欢
    • 2020-07-02
    • 1970-01-01
    • 2017-03-26
    • 1970-01-01
    • 2021-11-09
    • 2022-11-03
    • 1970-01-01
    • 2019-10-03
    • 1970-01-01
    相关资源
    最近更新 更多