为啥在匿名 PL/SQL 块中没有立即引发异常?

Posted

技术标签:

【中文标题】为啥在匿名 PL/SQL 块中没有立即引发异常?【英文标题】:Why is Exception not raised immediately in anonymous PL/SQL block?为什么在匿名 PL/SQL 块中没有立即引发异常? 【发布时间】:2015-10-17 20:42:38 【问题描述】:

在下面的代码中,当本金金额的输入小于零或负数时,它应该引发异常并退出。但是下面会执行块中的所有语句,并在最后显示写入异常块中的错误消息。

一旦引发异常,我希望 Oracle 退出。请帮我解决这个问题。

declare
    principle1 number;
    rate1 number;
    r1 number;
    years1 number;
    interest1 number;
    principle2 number;
    rate2 number;
    r2 number;
    years2 number;
    interest2 number;
    invalid_entry exception;
begin

    principle1 := &principle1_amount1;

    if (principle1 <= 0) then
      raise invalid_entry;
    end if;

    rate1 := &rate_interest1;
    r1 := rate1/100;
    years1 := &years1;
    interest1 := ComptInt_jk(principle1,r1,years1);

    dbms_output.put_line('The interest for the principle amount ' || principle1
                         || ' for ' || years1 || ' year/s at the rate of ' || rate1
                         ||'% is '||interest1);

    principle2 := &principle1_amount2;
    rate2 := &rate_interest1;
    r2 := rate2/100;
    years2 := &years2;
    interest2 := ComptInt_jk(principle2,r2,years2);

    dbms_output.put_line('The interest for the principle amount ' || principle2
                         || ' for ' || years2 || ' year/s at the rate of ' || rate2
                         ||'% is '||interest2);
exception
    when invalid_entry then
       dbms_output.put_line('The data entered cannot be zero or negative ');
end;
/

【问题讨论】:

首先,我不明白这个问题。您发布的代码是做什么或不做什么,您想更改什么?您希望代码做什么?其次,您发布了两个问题,这两个问题的主题都以“#Oracle#PL/SQL:”开头。这不是其他人可能会搜索的术语,因此我不确定您为什么要这样做。我的偏见是解决这两个主题,但我想我会问,因为你显然是故意这样做的。 我也正要在标题中提到主题标签(?);这就是标签的用途。你是说你收到了所有的dbms_output 消息吗?或者只是提示您输入所有替换变量?如果是后者,那么与您之前的问题一样,您不了解该块是如何解析的,并且正试图让 PL/SQL 做一些它不适合做的事情。 【参考方案1】:

"当输入到本金金额小于零或 -ve 时 应该引发异常并退出,但以下执行所有 块中的语句,最后显示错误消息 写在异常块中”

嗯,不完全是。发生的情况是 SQL*Plus 要求我们为 all 输入参数输入值。您的代码需要五个输入参数,因此它会显示五个提示。

一旦我们输入了所有需求参数,程序就会评估if (principle1&lt;=0 ) then,如果它是否定的,那么它会引发异常。然后控制流移动到异常块。

不显示任何其他消息。所以实际的代码没有被执行。看看吧:

.... 
 38* end;
Enter value for principle1_amount1: -89
old  16:     principle1:=&principle1_amount1;
new  16:     principle1:=-89;
Enter value for rate_interest1: 12
old  20:     rate1:=&rate_interest1;
new  20:     rate1:=12;
Enter value for years1: 12
old  22:     years1:=&years1;
new  22:     years1:=12;
Enter value for principle1_amount2: 12
old  25:     principle2:=&principle1_amount2;
new  25:     principle2:=12;
Enter value for rate_interest1: 12
old  26:     rate2:=&rate_interest1;
new  26:     rate2:=12;
Enter value for years2: 12
old  28:     years2:=&years2;
new  28:     years2:=12;
The data entered cannot be zero or negative

PL/SQL procedure successfully completed.

SQL> 

【讨论】:

以上是关于为啥在匿名 PL/SQL 块中没有立即引发异常?的主要内容,如果未能解决你的问题,请参考以下文章

约束违反异常 PL/SQL

匿名 pl/sql 块中的声明顺序

我可以在调用同一过程后将 PL/SQL 过程放在匿名块中吗?

如何在匿名 PL/SQL 块中自动显示所有 SQL 语句的输出

Oracle 匿名 PL/SQL 块中缺少关键字错误

从 pl/sql 异常块中“一次”关闭所有游标