我正在编写一个脚本来执行多个唯一查询(不能放在循环中)。添加异常处理程序时,一旦发生第一个错误,便会处理异常,但编译器会退出该块并终止程序。
如何使我的程序处理异常并继续执行下一个查询?
下面是我一直在使用的代码:
DECLARE
NEW_VAR1 VARCHAR2(20000);
table_does_not_exist exception;
PRAGMA EXCEPTION_INIT(table_does_not_exist, -942);
BEGIN
DBMS_output.put_line('Query 1 Execution');
EXECUTE IMMEDIATE 'BEGIN
SELECT "defaultpwd" INTO :out1 from sys.user$ where name="APEX_040000" and substr(spare4,3,40)=rawtohex(utl_raw.cast_to_varchar2(sys.dbms_crypto.hash(utl_raw.cast_to_raw("oracle")||hextoraw(substr(spare4,43,20)), 3))) UNION SELECT "defaultpwd" from sys.user$ where name="APEX_040000" and password="EE7785338B8FFE3D";
END;'
USING out NEW_VAR1;
DBMS_output.put_line(NEW_VAR1);
DBMS_output.put_line('Query 2 Execution');
EXECUTE IMMEDIATE 'BEGIN
SELECT "defaultpwd" INTO :out2 from sys.user$ where name="APEX_040000" and substr(spare4,3,40)=rawtohex(utl_raw.cast_to_varchar2(sys.dbms_crypto.hash(utl_raw.cast_to_raw("oracle")||hextoraw(substr(spare4,43,20)), 3))) UNION SELECT "defaultpwd" from sys.user$ where name="APEX_040000" and password="EE7785338B8FFE3D";
END;'
USING out NEW_VAR1;
DBMS_output.put_line(NEW_VAR1);
EXCEPTION
WHEN table_does_not_exist THEN
DBMS_output.put_line('Table does not exist!!');
WHEN others then
DBMS_output.put_line('Error!!');
END;
在这种情况下,期望的结果是:
Query 1 Execution
Error!!
Query 2 Execution
Error!!
实际结果是:
Query 1 Execution
Error!!
如果上述代码效率不高,我可以选择执行多种不同查询的替代方法。
我认为您需要为每个查询使用不同的异常块。像这样的东西:
DECLARE
NEW_VAR1 VARCHAR2(20000);
table_does_not_exist exception;
PRAGMA EXCEPTION_INIT(table_does_not_exist, -942);
BEGIN
BEGIN
DBMS_output.put_line('Query 1 Execution');
EXECUTE IMMEDIATE 'BEGIN
SELECT "defaultpwd" INTO :out1 from sys.user$ where name="APEX_040000" and substr(spare4,3,40)=rawtohex(utl_raw.cast_to_varchar2(sys.dbms_crypto.hash(utl_raw.cast_to_raw("oracle")||hextoraw(substr(spare4,43,20)), 3))) UNION SELECT "defaultpwd" from sys.user$ where name="APEX_040000" and password="EE7785338B8FFE3D";
END;'
USING out NEW_VAR1;
DBMS_output.put_line(NEW_VAR1);
EXCEPTION
WHEN table_does_not_exist THEN
DBMS_output.put_line('Table does not exist!!');
WHEN others then
DBMS_output.put_line('Error!!');
END;
BEGIN
DBMS_output.put_line('Query 2 Execution');
EXECUTE IMMEDIATE 'BEGIN
SELECT "defaultpwd" INTO :out2 from sys.user$ where name="APEX_040000" and substr(spare4,3,40)=rawtohex(utl_raw.cast_to_varchar2(sys.dbms_crypto.hash(utl_raw.cast_to_raw("oracle")||hextoraw(substr(spare4,43,20)), 3))) UNION SELECT "defaultpwd" from sys.user$ where name="APEX_040000" and password="EE7785338B8FFE3D";
END;'
USING out NEW_VAR1;
DBMS_output.put_line(NEW_VAR1);
EXCEPTION
WHEN table_does_not_exist THEN
DBMS_output.put_line('Table does not exist!!');
WHEN others then
DBMS_output.put_line('Error!!');
END;
END;
原则上,您必须这样做:
DECLARE
NEW_VAR1 VARCHAR2(20000);
table_does_not_exist exception;
PRAGMA EXCEPTION_INIT(table_does_not_exist, -942);
BEGIN
BEGIN
DBMS_output.put_line('Query 1 Execution');
EXECUTE IMMEDIATE 'BEGIN
SELECT "defaultpwd" INTO :out1 from sys.user$ where name="APEX_040000" and substr(spare4,3,40)=rawtohex(utl_raw.cast_to_varchar2(sys.dbms_crypto.hash(utl_raw.cast_to_raw("oracle")||hextoraw(substr(spare4,43,20)), 3))) UNION SELECT "defaultpwd" from sys.user$ where name="APEX_040000" and password="EE7785338B8FFE3D";
END;'
USING out NEW_VAR1;
DBMS_output.put_line(NEW_VAR1);
EXCEPTION
WHEN table_does_not_exist THEN
DBMS_output.put_line('Table does not exist!!');
WHEN others then
DBMS_output.put_line('Error!!');
END;
BEGIN
DBMS_output.put_line('Query 2 Execution');
EXECUTE IMMEDIATE 'BEGIN
SELECT "defaultpwd" INTO :out2 from sys.user$ where name="APEX_040000" and substr(spare4,3,40)=rawtohex(utl_raw.cast_to_varchar2(sys.dbms_crypto.hash(utl_raw.cast_to_raw("oracle")||hextoraw(substr(spare4,43,20)), 3))) UNION SELECT "defaultpwd" from sys.user$ where name="APEX_040000" and password="EE7785338B8FFE3D";
END;'
USING out NEW_VAR1;
DBMS_output.put_line(NEW_VAR1);
EXCEPTION
WHEN table_does_not_exist THEN
DBMS_output.put_line('Table does not exist!!');
WHEN others then
DBMS_output.put_line('Error!!');
END;
END;
或放入循环中:
BEGIN
FOR i IN 1..2 LOOP
BEGIN
DBMS_output.put_line('Query '||i||' Execution');
EXECUTE IMMEDIATE ...
EXCEPTION
WHEN table_does_not_exist THEN
DBMS_output.put_line('Table does not exist!!');
WHEN others then
DBMS_output.put_line('Error!!');
END;
END LOOP;
END;
但是您的代码有几个错误/缺陷:
EXECUTE IMMEDIATE
要求完全返回one行。由于UNION
,这不太可能。EXECUTE IMMEDIATE 'SELECT ... FROM ...' INTO NEW_VAR1;
sys.user$
有任何列defaultpwd
(小写)WHEN others then DBMS_output.put_line('Error!!' || SQLERRM);
查看实际错误,否则将其隐藏。因为您是SQL的初学者,所以情况甚至更糟。PASSWORD
进行比较,请简化=
或<>
SELECT ... INTO NEW_VAR1 FROM ...
。不需要EXECUTE IMMEDIATE
。动态SQL有什么特殊原因吗?您运行的查询中没有dynamic