是否有一个类似SQLERRM
或SQLCODE
包含引发错误的语句的变量?
例:
/* if some error raised from this code and I want to know which statement cause the failure.. I wish to use some oracle varaible to know it */ begin select * from t1; select * from t2; exception when others dbms_output.put_line(sqlerrm || ' raised from this statement:' ||; end; -- excepted result: no data found raised from this statement: select * from t2
APC.. 5
简单的答案,不。通过定义异常处理程序,您将丢失一些信息。对于未处理的异常,您会收到一条包含行号的错误消息。但是显然我们需要处理错误,记录错误等。因此,没有行号是很垃圾的。
幸运的是,有两种选择。在旧版本的Oracle中,我们可以使用dbms_utility.format_error_backtrace()
和dbms_utility.format_error_stack()
获取一些有用的信息,包括行号。它非常笨拙,并且(特别是用于回溯)非常冗长。
在Oracle 12c中,我们得到了一个专门用于PL / SQL调用堆栈的完整软件包:UTL_CALL_STACK。它是一个位盒,需要多个调用才能得到,但是我们可以使用来检索特定的行号unit_line()
。蒂姆·霍尔(Tim Hall)对新功能进行了典型的精美介绍。了解更多。
要考虑的另一件事是良好的程序设计如何解决此问题。特别是单一责任原则。这是程序设计的基本准则:程序单元应该做一件事。如果我们问“通过此错误执行哪个命令”的问题,则可能表明我们违反了SRP。
让我们辞职代码,使其遵循以下设计原则:
declare type nt1 is table of t1%rowtype; type nt2 is table of t2%rowtype; l_t1 nt1; l_t2 nt2; x_t1_ndf exception; x_t2_ndf exception; function get_t1 return nt1 is return_value nt1; begin select * bulk collect into return_value from t1; if return_value.count() = 0 then raise x_t1_ndf; end if; return return_value; end get_t1; function get_t2 return nt2 is return_value nt2; begin select * bulk collect into return_value from t2; if return_value.count() = 0 then raise x_t2_ndf; end if; return return_value; end get_t2; begin l_t1 := get_t1; l_t2 := get_t2; exception when x_t1_ndf then dbms_output.put_line('T1 has no data'); when x_t2_ndf then dbms_output.put_line('T2 has no data'); end;
显然,键入的内容比原始代码多,但是部分原因是,此玩具是完整的工作代码,与您发布的代码不同。同样在现实生活中,这些模块将是离散的单元,而不是匿名块中的私有功能,因此我们可以在其他多个程序中重复使用它们。
这dbms_output.put_line()
也不是处理异常的正确方法,但是我已经离开了,因为这就是您的代码所做的。
简单的答案,不。通过定义异常处理程序,您将丢失一些信息。对于未处理的异常,您会收到一条包含行号的错误消息。但是显然我们需要处理错误,记录错误等。因此,没有行号是很垃圾的。
幸运的是,有两种选择。在旧版本的Oracle中,我们可以使用dbms_utility.format_error_backtrace()
和dbms_utility.format_error_stack()
获取一些有用的信息,包括行号。它非常笨拙,并且(特别是用于回溯)非常冗长。
在Oracle 12c中,我们得到了一个专门用于PL / SQL调用堆栈的完整软件包:UTL_CALL_STACK。它是一个位盒,需要多个调用才能得到,但是我们可以使用来检索特定的行号unit_line()
。蒂姆·霍尔(Tim Hall)对新功能进行了典型的精美介绍。了解更多。
要考虑的另一件事是良好的程序设计如何解决此问题。特别是单一责任原则。这是程序设计的基本准则:程序单元应该做一件事。如果我们问“通过此错误执行哪个命令”的问题,则可能表明我们违反了SRP。
让我们辞职代码,使其遵循以下设计原则:
declare type nt1 is table of t1%rowtype; type nt2 is table of t2%rowtype; l_t1 nt1; l_t2 nt2; x_t1_ndf exception; x_t2_ndf exception; function get_t1 return nt1 is return_value nt1; begin select * bulk collect into return_value from t1; if return_value.count() = 0 then raise x_t1_ndf; end if; return return_value; end get_t1; function get_t2 return nt2 is return_value nt2; begin select * bulk collect into return_value from t2; if return_value.count() = 0 then raise x_t2_ndf; end if; return return_value; end get_t2; begin l_t1 := get_t1; l_t2 := get_t2; exception when x_t1_ndf then dbms_output.put_line('T1 has no data'); when x_t2_ndf then dbms_output.put_line('T2 has no data'); end;
显然,键入的内容比原始代码多,但是部分原因是,此玩具是完整的工作代码,与您发布的代码不同。同样在现实生活中,这些模块将是离散的单元,而不是匿名块中的私有功能,因此我们可以在其他多个程序中重复使用它们。
这dbms_output.put_line()
也不是处理异常的正确方法,但是我已经离开了,因为这就是您的代码所做的。