在 Oracle 中执行 DELETE 查询时如何重现异常
Posted
技术标签:
【中文标题】在 Oracle 中执行 DELETE 查询时如何重现异常【英文标题】:How to reproduce exception when performing DELETE query in Oracle 【发布时间】:2015-08-26 09:16:26 【问题描述】:我想在从 Oracle 数据库中的表执行 DELETE 查询以进行某些测试时重现异常。
但是删除的时候出现异常怎么办呢?
【问题讨论】:
您需要先了解 run time vs compile time 错误。 PL/SQL 异常块将捕获运行时错误,而不是编译时错误。 感谢您指出这一点,但我已经知道了。我的问题是在执行 DELETE 查询时如何发生异常(有多少种方式?),而不是如何处理异常。 您是否在询问 DELETE 语句中出现错误的所有可能性? 答案取决于您想要发生的异常。如果您想要删除零异常,请在查询中包含where 1/0 = 1
。我认为这是您要强制执行的其他一些例外情况。
@ShannonSeverance 是的,通常 DELETE 查询应该运行得很好,我只是认为锁定该 TABLE 可能会强制异常,但还不知道该怎么做。
【参考方案1】:
但是删除的时候出现异常怎么办呢?
请记住,PL/SQL 异常块会捕获运行时错误,而不是编译时错误。
首先在没有任何异常块的情况下执行代码,因此您将获得具有精确行号的整个错误堆栈。
基于完整的错误堆栈,如果您想优雅地处理异常,则创建您的用户定义的异常并在EXCEPTION块中处理它们。 p>
例如,
无异常块
SQL> BEGIN
2 DELETE FROM emp WHERE loc = 'NEW_YORK';
3 END;
4 /
DELETE FROM emp WHERE loc = 'NEW_YORK';
*
ERROR at line 2:
ORA-06550: line 2, column 25:
PL/SQL: ORA-00904: "LOC": invalid identifier
ORA-06550: line 2, column 3:
PL/SQL: SQL Statement ignored
所以,我可以在错误堆栈中看到 ORA-00904 Invalid Identifier 错误。
处理异常
SQL> SET serveroutput ON
SQL> DECLARE
2 invalid_identifier EXCEPTION;
3 PRAGMA EXCEPTION_INIT(invalid_identifier, -904);
4 text VARCHAR2(128);
5 BEGIN
6 text:='DELETE FROM emp WHERE loc = ''NEW_YORK''';
7 EXECUTE immediate text;
8 EXCEPTION
9 WHEN invalid_identifier THEN
10 dbms_output.put_line('Invalid identifier error in delete statement');
11 END;
12 /
Invalid identifier error in delete statement
PL/SQL procedure successfully completed.
SQL>
DBMS_OUTPUT 仅用于演示目的,实际上您会记录错误。
【讨论】:
【参考方案2】:您必须有一个条件,您希望根据该条件引发与业务逻辑相关的异常。但是,如果你想强制引发异常,你可以定义你的异常并像 'raise your_exception' 一样引发它;
【讨论】:
【参考方案3】:create table test_delete(a varchar2(10));
insert into test_delete values('abc');
insert into test_delete values('abc');
insert into test_delete values('err123');
insert into test_delete values('err3');
CREATE OR REPLACE TRIGGER delete_exeption
BEFORE
DELETE
ON test_delete
REFERENCING NEW AS NEW OLD AS OLD
FOR EACH ROW
begin
if( INSTR( :old.a, 'err') > 0 ) then
raise_application_error(-20000,'Error');
end if;
end;
/
delete from test_delete where a = 'abc'; -- no error
delete from test_delete where a = 'err123'; -- error
只有在删除列a中包含“err”的行时才会发生错误
【讨论】:
【参考方案4】:如果我理解正确,您会寻找异常的语义。 这是一个例子:
DECLARE
pe_ratio NUMBER(3,1);
BEGIN
SELECT price / earnings INTO pe_ratio FROM stocks
WHERE symbol = 'XYZ'; -- might cause division-by-zero error
INSERT INTO stats (symbol, ratio) VALUES ('XYZ', pe_ratio);
COMMIT;
EXCEPTION -- exception handlers begin
WHEN ZERO_DIVIDE THEN -- handles 'division by zero' error
INSERT INTO stats (symbol, ratio) VALUES ('XYZ', NULL);
COMMIT;
...
WHEN OTHERS THEN -- handles all other errors
ROLLBACK;
END; -- exception handlers and block end here
如您所见,您可以使用预定义的例外或对其他人使用“WHEN OTHER THEN”子句,实际上您可以将它用于所有例外。 实际上,我从以下链接中的 Oracle 文档中复制了这个示例,在这里您还可以找到预定义异常的列表: https://docs.oracle.com/cd/B10500_01/appdev.920/a96624/07_errs.htm
【讨论】:
以上是关于在 Oracle 中执行 DELETE 查询时如何重现异常的主要内容,如果未能解决你的问题,请参考以下文章
oracle 10g R2数据库,用pl/sql developer 删除数据时,执行DELETE FROM TABLE1后就一直停在执行的状态,