假设我有3个程序一起运行,分别插入记录A,B,C:
exec P1
执行P2
执行P3
假设P2会抛出异常,而P1和P3都可以。
我的预期流量是: 运行P1 - >插入 - >运行P2 - >遇到异常 - >回滚 - >停止运行P3
最终的预期结果没有任何改变。
我已经为P2定义了异常和异常处理,它将回滚。但是,我无法阻止它运行P3,即C仍然插入。
谷歌告诉我有WHENEVER SQLERROR EXIT ROLLBACK
,但我发现它不能用于自定义异常。换句话说,它仅适用于Oracle官方例外,例如:
第2行的错误: ORA-06550:第2行第10栏: PLS-00201:标识符' COLUMN_DOES_NOT_EXIST'必须申报 ORA-06550:第2行第3列: PL / SQL:忽略SQL语句
为了达到预期的效果,我的想法是(但我不知道该怎么做!):
向P2添加异常处理,以便它可以阻止P3运行。
在运行程序之前运行WHENEVER SQLERROR EXIT ROLLBACK
。 (但它只能用于Oracle官方异常,而不是我定义的异常)
如果您能修复任何一个,我感谢您的帮助。
以下是我的代码供您参考:
PROCEDURE INSERT(
INPUT IN TABLE.INPUT%TYPE DEFAULT NULL
) AS
BEGIN
IF INPUT NOT IN ('A','B','C') THEN
RAISE invalid_input;
END IF;
INSERT INTO (...) VALUES (...);
EXCEPTION
WHEN invalid_input THEN
DBMS_OUTPUT.PUT_LINE ('Invalid input' );
rollback; ---How to stop next procedure from running?
WHEN others THEN
rollback;
END;
我跑的时候 执行INSERT(A) 执行INSERT(Y) 执行INSERT(C), 结果是C被插入,而我想要什么都没有改变。
答案 0 :(得分:0)
我在你的程序中添加了一行(并改为运行测试示例):
create or replace PROCEDURE ins(P_INPUT IN t.INPUT%TYPE DEFAULT NULL) AS
invalid_input exception;
BEGIN
IF P_INPUT NOT IN ('A','B','C') THEN
RAISE invalid_input;
END IF;
INSERT INTO t (INPUT) VALUES (P_INPUT);
EXCEPTION
WHEN invalid_input THEN
DBMS_OUTPUT.PUT_LINE ('Invalid input' );
rollback; ---How to stop next procedure from running?
raise; -- re-raise exception added
WHEN others THEN
rollback;
END;
表:
create table t (input varchar2(1));
测试脚本:
SQL> declare
total_rows number;
begin
ins('A');
ins('D');
ins('C');
exception
when others then
select count(*) into total_rows from t;
dbms_output.put_line('Error ocured. Total rows in table T: ' || total_rows);
end;
/
Invalid input
Error ocured. Total rows in table T: 0
PL/SQL procedure successfully completed.
据我了解,这是你想要的结果。