从 PL/SQL 返回错误

Posted

技术标签:

【中文标题】从 PL/SQL 返回错误【英文标题】:Returning errors from PL/SQL 【发布时间】:2011-02-07 13:48:16 【问题描述】:

快速直接的问题:

我正在编写一个 PL/SQL 存储过程。它包含一些可能失败的execute immediate 调用。我不想引发错误。我希望存储过程干净地完成其执行并返回错误列表。比如:

for vRecord in vCursor
loop
    begin
        execute immediate 'insert into t(a) values (' || vRecord.val || ')';
    when others then
        -- store the error somewhere to return it!!
    end;
end loop;

所以我的问题是:返回这些错误的推荐方法是什么?一张桌子?输出参数?

非常感谢。

【问题讨论】:

【参考方案1】:

哇,我刚刚在另一个帖子中回答了类似的问题,到目前为止很奇怪。如果您只想记录错误(或消息),请使用 LOG 表并使用自治事务:

见here

【讨论】:

谢谢!我想到了那个。虽然不知道这是否是最好的选择。使用 TABLE 只是为了返回错误似乎是一种过度杀戮......无论如何感谢您的建议! 永远不要过度记录错误,这是一种很好的做法;)并且您可以对随着时间的推移发生的事情进行审计跟踪,假设这是您将以某种频率运行的事情。 你真的应该使用类似 dbms_utility.format_error_stack||dbms_utility.format_error_backtrace 而不仅仅是 SQLERRM。【参考方案2】:

从版本 10g 第 2 版开始,您可以使用 DML 错误日志将所有错误存储在一个特殊的表中。你可以在这里阅读:

http://download.oracle.com/docs/cd/E11882_01/appdev.112/e16760/d_errlog.htm#ARPLS680

基于您发布的代码的一些其他建议:

1) 这里不需要使用动态SQL。改用这个:

insert into t(a) values (vRecord.val);

2) 这里没有必要使用循环。只需使用 INSERT/SELECT 代替:

insert into t(a) select [the query from your vCursor here]

问候, 抢。

【讨论】:

非常感谢 Rob 的回答。我将看一下 DML 错误日志记录。也感谢您的建议。但是,我发布的只是一个示例代码。我的实际代码确实需要动态 SQL。 使用 Oracle 的内置功能而不是滚动我们自己的功能始终是最好的主意。但是,我不确定将 DML 错误记录与动态 SQL 一起使用会有多容易。这取决于 SQL 的动态方式... 是的。表 - 在这种情况下为 t - 不应该是动态的 :-)

以上是关于从 PL/SQL 返回错误的主要内容,如果未能解决你的问题,请参考以下文章

PL/SQL:无法从包元素 PL/SQL 返回值

从 PL/SQL 函数返回表 - 不正确的数据类型

PL/sql 函数返回多行错误

在 pl/sql 函数中选择子句返回错误值

将退出代码从 Java 返回到 PL/SQL

如何检查 ref 游标是不是从 pl/sql 过程返回数据