【问题标题】:Checking for Error during execution of a procedure in oracle在 oracle 中执行过程期间检查错误
【发布时间】:2011-02-13 15:10:48
【问题描述】:
create or replace procedure proc_advertisement(CustomerID in Number,
NewspaperID in number,
StaffID in Number,
OrderDate in date,
PublishDate in date,
Type in varchar,      
Status in varchar, 
Units in number) is 

begin 

insert into PMS.Advertisement(CustomerID, NewspaperID, StaffID, OrderDate, PublishDate, 
Type, Status, Units) 
values(CustomerID,NewspaperID, StaffID, OrderDate, PublishDate, 
Type, Status, Units); 
dbms_output.put_line('Advertisement Order Placed Successfully'); 
end;

如何检查程序执行过程中是否发生任何错误,如果发生任何错误,那么我希望显示错误消息。

【问题讨论】:

    标签: oracle stored-procedures


    【解决方案1】:

    首先,如果在运行过​​程中发生任何错误,Oracle 本身会引发错误消息 - 例如:

    ORA-02291: integrity constraint (EMP.MGR_FK) violated - parent key not Found
    

    您可以通过编写异常处理程序来显式处理错误,但除非您做得很好,否则您很可能只是混淆了问题。例如,您可以简单地添加这个(就在您的程序结束之前:

    EXCEPTION
        WHEN OTHERS THEN
            RAISE_APPLICATION_ERROR(-20001,'An error occured');
    

    但是现在您的用户将不知道什么样的错误,而之前他们可以推断出指定的 Manager 不存在。您也可以像这样显示原始错误:

    EXCEPTION
        WHEN OTHERS THEN
            RAISE_APPLICATION_ERROR(-20001,'An error occured: '||SQLERRM);
    

    如果这增加了任何价值。或者您可以只显示一般错误,然后将 SQLERRM 的值写入日志表。

    您还可以处理特定的异常:例如

    PROCEDURE ... IS
        e_invalid_fk EXCEPTION;
        PRAGMA EXCEPTION_INIT(e_invalid_fk,-2291);
    BEGIN
        ...
    EXCEPTION
        WHEN e_invalid_fk THEN
            IF SQLERRM LIKE '%(EMP.MGR_FK)%' THEN
                raise_application_error(-20001,'Invalid manager specified');
            ELSE
               RAISE;
            END IF;
    END;
    

    注意 RAISE:如果您的异常处理程序的任何部分都没有发出 RAISE 或 RAISE_APPLICATION_ERROR,那么您实际上是在掩盖异常 - 用户会认为该过程有效。

    顺便说一句,DBMS_OUTPUT.PUT_LINE 非常适合在 SQL Plus 或 IDE 中尝试和调试,但它在实际代码中没有位置,因为调用该过程的用户和应用程序永远不会看到它产生的输出。

    【讨论】:

    • +1 - 提出了我要提出的所有观点,特别是 DBMS_OUTPUT 不适合错误处理(少数特殊情况下的例外)。
    • +1,我也喜欢 raise_application_error(xxx, msg, TRUE),这样可以保留错误堆栈。它对最终用户和支持都很有用。
    • 我总是忘记第三个参数!
    猜你喜欢
    • 2018-07-01
    • 2019-08-12
    • 1970-01-01
    • 2020-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-12
    • 1970-01-01
    相关资源
    最近更新 更多