【发布时间】:2015-01-14 13:36:45
【问题描述】:
我的数据库中有多个存储过程调用多个存储过程。举一个小例子,我在下面构建了其中一些的虚构版本。在我的例子中,一个Java程序调用calculate_bill,它调用calculate_commission,它又调用update_record。
我希望就如何最好地将错误消息向上传播到调用 Java 层获得一些建议,以便用户获得与错误发生位置相对应的精确错误消息。
我真的很坚持这一点。在我的示例中,我使用raise_application_error 进行了玩弄,只是不断地将其洗牌。我在下面的远程操作方式是否正确?还是相关程序中的一个 raise_application_error 就足够了,不需要pragma exception init 等?
为了说明我的意思,在下面的示例中,如果用户输入的数字对应于由于不存在而无法更新的记录,我希望他们收到消息: “计算账单错误。计算佣金错误。不存在要更新的记录”或类似的内容。
那么两个问题:
- 为应用层的最终用户在堆栈中向上传递错误消息的最佳实践、最有效、最整洁的方法是什么?
- 是否有人对代码输出更整洁有任何建议,即连接这些错误以使其更有意义的最佳方法?我非常愿意接受有关如何使这项工作最好的任何建议,因为我完全没有这方面的经验。
示例: (代码错误):
-20000 : Error in top level procedure
-20001 : Error in middle level procedure
-20002 : Error in bottom level procedure
Java 代码:
try {
// call calculate_bill
exception (SQLException ex)
// output oracle code and relevant message.
Oracle 代码:
create or replace procedure calculate_bill(in_num NUMBER)
is
error_calculating_commission EXCEPTION;
error_updating_record EXCEPTION;
PRAGMA EXCEPTION_INIT (error_calculating_commission, -20001);
PRAGMA EXCEPTION_INIT (error_updating_record , -20002);
begin
if in_num > 2 then
calculate_commission(in_num);
else
raise_application_error(-20000, 'Error calculating bill. ' || 'Record number doesn''t exist.', false);
end if;
exception
when error_calculating_commission then
raise_application_error(SQLCODE, 'Error calculating bill. ' || SQLERRM, false);
when error_updating_record then
raise_application_error(SQLCODE, 'Error calculating bill. ' || SQLERRM, false);
when others then
raise_application_error(-20000, 'Unknown error encountered calculating bill.', false);
end;
create or replace procedure calculate_commission(in_num NUMBER)
is
begin
if in_num < 30 then
raise_application_error(-20001, 'Number too small to calculate commission.', false);
elsif in_num >= 30 and < 40 then
declare
error_storing_record EXCEPTION;
PRAGMA EXCEPTION_INIT (error_storing_record , -20002);
begin
update_record(in_num);
exception
when error_storing_record then
raise_application_error(SQLCODE, 'Error calculating commission. ' || SQLERRM, false);
when others then
raise_application_error(-20001, 'Unknown error encountered calculating commission.', false);
else
raise_application_error(-20001, 'Number too large to calculate commission', false);
end if;
end;
create or replace procedure update_record(in_num NUMBER)
is
begin
//some SQL query with a where clause, where in_num equals something
exception
when no_data_found then
raise_application_error(-20002, 'No record exists to be updated', false);
when others then
raise_application_error(-20002, 'Unknown error encountered updating record.', false);
end if;
end;
注意:我知道这个例子有点做作。我只是想保持简短。
【问题讨论】:
-
一种方法是通过存储过程接口本身作为输出参数传递错误代码和描述。这样做应该会给您更多的控制权,并且您会更少地受到 Oracle 的错误处理渗透能力的限制。我不在 Oracle 上工作,所以我不会谈论它可能完全支持的其他设计。希望甲骨文专家能参与进来。
-
我希望如此,因为您的建议让我转了一圈!当我开始时,这正是我正在做的事情,我被警告不要这样做,因为将错误作为参数传递被认为是不好的做法。这是我的“替代”方法,我正在寻找整理帮助!
标签: sql oracle exception plsql exception-handling