我在PL / SQL过程中使用了几个连续的SELECT INTO语句。如果这些Select语句中的任何一个导致NO DATA FOUND,我想以一致的方式处理错误。有没有办法在几个Select语句的同一过程中使用一个EXCEPTION例程?我想知道哪个特定的选择失败,以便我能给出正确的信息。
Declare
l_smtp_hostname varchar2(1024);
l_smtp_port varchar2(1024);
l_music_db_site varchar2(1024);
Begin
Select lu_value into l_smtp_hostname from mail_lookup
Where lu_type = 'smtp_hostname';
Select lu_value into l_smtp_port from mail_lookup
Where lu_type = 'smtp_port';
Select lu_value into l_music_db_site from mail_lookup
Where lu_type = 'music_db_site';
End;
感谢您查看此内容。
答案 0 :(得分:3)
实际上,可能不是。
您可以拥有一个异常处理程序,但后来您不知道哪个步骤失败了。您可能会从错误堆栈中获取错误的行号,然后从dba_source
解析数据(假设您确实有一个存储过程而不是匿名PL / SQL块)来查找该语句。但那是一项艰苦的工作。
Declare
l_smtp_hostname varchar2(1024);
l_smtp_port varchar2(1024);
l_music_db_site varchar2(1024);
Begin
Select lu_value into l_smtp_hostname from mail_lookup
Where lu_type = 'smtp_hostname';
Select lu_value into l_smtp_port from mail_lookup
Where lu_type = 'smtp_port';
Select lu_value into l_music_db_site from mail_lookup
Where lu_type = 'music_db_site';
Exception
When no_data_found
Then
<<do something>>
End;
您可以添加一个跟踪您在此过程中所处位置的变量。这可行,但可能导致一些丑陋的代码
Declare
l_smtp_hostname varchar2(1024);
l_smtp_port varchar2(1024);
l_music_db_site varchar2(1024);
l_tracker varchar2(30);
Begin
l_tracker := 'smtp_hostname';
Select lu_value into l_smtp_hostname from mail_lookup
Where lu_type = l_tracker;
l_tracker := 'smtp_port';
Select lu_value into l_smtp_port from mail_lookup
Where lu_type = l_tracker;
l_tracker := 'music_db_site';
Select lu_value into l_music_db_site from mail_lookup
Where lu_type = l_tracker;
Exception
When no_data_found
Then
dbms_output.put_line( 'Error at ' || l_tracker );
<<do something>>
End;
大多数情况下,您希望单独处理每个例外。通常通过调用记录错误的过程。
Declare
l_smtp_hostname varchar2(1024);
l_smtp_port varchar2(1024);
l_music_db_site varchar2(1024);
Begin
begin
Select lu_value into l_smtp_hostname from mail_lookup
Where lu_type = 'smtp_hostname';
exception
when no_data_found then
log_error( 'smtp_hostname', <<other parameters>> );
end;
begin
Select lu_value into l_smtp_port from mail_lookup
Where lu_type = 'smtp_port';
exception
when no_data_found then
log_error( 'smtp_port', <<other parameters>> );
end;
begin
Select lu_value into l_music_db_site from mail_lookup
Where lu_type = 'music_db_site';
exception
when no_data_found then
log_error( 'music_db_site', <<other parameters>> );
end;
End;
当然,您可以将该代码并将其分解为一个函数,该函数需要lu_type
并返回lu_value
而不是复制块中的代码。
Declare
l_smtp_hostname varchar2(1024);
l_smtp_port varchar2(1024);
l_music_db_site varchar2(1024);
function get_lu_value( p_lu_type in mail_lookup.lu_type%type )
return mail_lookup.lu_value%type
is
l_val mail_lookup.lu_value%type;
begin
select lu_value
into l_val
from mail_lookup
where lu_type = p_lu_type;
return l_val;
exception
when no_data_found
then
<<do something>>
end;
Begin
l_smtp_hostname := get_lu_value( 'smtp_hostname' );
l_smtp_port := get_lu_value( 'smtp_port' );
l_music_db_site := get_lu_value( 'music_db_site' );
End;
答案 1 :(得分:2)
您可以将每个选择包装在其自己的块中并调用公共异常处理程序,或者执行类似这样的操作,在您通过代码时设置位置变量,如果发生异常,请记录该值的位置,所以你知道它失败的地方:
Declare
l_smtp_hostname varchar2(1024);
l_smtp_port varchar2(1024);
l_music_db_site varchar2(1024);
v_location varchar2(50);
err_nbr NUMBER; -- Holds a SQL error number if an exception occurs.
err_msg VARCHAR2(1000); -- Holds a SQL error message if an exception occurs.
err_string VARCHAR2(2000);
Begin
v_location := 'location_1';
Select lu_value into l_smtp_hostname from mail_lookup
Where lu_type = 'smtp_hostname';
v_location := 'location_2';
Select lu_value into l_smtp_port from mail_lookup
Where lu_type = 'smtp_port';
v_location := 'location_3';
Select lu_value into l_music_db_site from mail_lookup
Where lu_type = 'music_db_site';
Exception
When NO_DATA_FOUND then
err_nbr := SQLCODE;
err_msg := SUBSTR(SQLERRM, 1, 1000);
err_string := 'ERROR: ' || err_nbr || ' occurred: ' || err_msg;
UTL_MAIL.send(sender => 'program_name@your_company.com',
recipients => 'support_team@your_company.com',
subject => 'ERROR in <program_name>',
message => 'Select failed at: ' || v_location || CHR(10)||CHR(10)||err_string);
RAISE; -- re-raise the error so the program fails.
End;