我试图在我的oracle开发人员版本中执行下面的pl sql块。我调用了函数和过程并且它可以运行罚款。但是如果我的查询没有被执行,我无法调用异常。我有一直试图通过传递一个字符串值而不是int值来得到一个错误的查询。所以它抛出错误但我还需要在出现这种错误时才能执行异常块。块2应该通过异常,因为我传递字符串值。但是异常块没有得到调用,任何帮助?以下是我的块
DECLARE
DBCID INT := 102;
CNT INT;
BEGIN
SELECT DEVOPS_ISDBCEXECUTED(DBCID, 'DDL') INTO CNT FROM DUAL;
IF (CNT = 0) THEN
BEGIN
DEVOPS_DBCINSERT (DBCID,'DDL','hsolanki','Prj1','Item1','avarne');
BEGIN
DECLARE W_CNT int;
BEGIN
SELECT COUNT(*) INTO W_CNT FROM HS WHERE NAM = 'DK'; //block 1
IF (W_CNT = 0) THEN
INSERT INTO HS
(NAM, AGE)
VALUES ('Dk',8);
END IF;
END;
END;
BEGIN
DECLARE W_CNT int;
BEGIN
SELECT COUNT(*) INTO W_CNT FROM HS WHERE NAM = 'Ab';
IF (W_CNT = 0) THEN
INSERT INTO HS
(NAM, AGE) //block 2
VALUES ('Ab',s);
END IF;
END;
END;
DEVOPS_DBCUPDATE(DBCID, NULL,'SUCCESS');
EXCEPTION
WHEN OTHERS THEN
DBMS_OUTPUT.PUT_LINE ('ERROR OCCURED : ' || sqlerrm);
DEVOPS_DBCUPDATE (DBCID,sqlerrm,'Failed');
rollback;
END;
END IF;
END;
答案 0 :(得分:1)
您的异常处理块在' IF(CNT = 0)THEN .. END IF'块。如果传递一个字符串值,很可能是在第一个函数调用(SELECT DEVOPS_ISDBCEXECUTED ...)中抛出了异常,该调用未被保护'由一个excpetion处理程序。您需要将异常处理程序移动到最外面的块,例如:
DECLARE
DBCID INT := 102;
CNT INT;
BEGIN
....
EXCEPTION
WHEN OTHERS THEN
...
END;
答案 1 :(得分:1)
所以我们知道......
DEVOPS_DBCUPDATE是更新表
的过程
......和......
异常我正在调用DEVOPS_DBCUPDATE ...我的表没有得到更新
......和......
我不知道什么是pragma autonomous_transaction
完全提出这些线索,我们可以看到EXCEPTION块中的rollback
将消除前一次调用DEVOPS_DBCUPDATE()
所执行的表的更改,所以只有似乎好像没有执行EXCEPTION块(检查是否显示DBMS_OUTPUT
消息会确认它正在被调用)。
无论如何,解决方案是使DEVOPS_DBCUPDATE()
在嵌套事务中运行,因此无论更广泛的事务中发生什么,都会应用更改。我们使用autonomous_transaction
pragma执行此操作。
显然我不知道代码的确切结构,但它看起来像这样:
create or replace procedure DEVOPS_DBCUPDATE( ... ) is
pragma autonomous_transaction;
begin
update your_table
set ....
commit;
end;
过程中的COMMIT会将更改保留到您的表中,但不会在外部事务中保存任何内容。因此,EXCEPTION块中的rollback
仍会将插入反转到HS
表中。
如果使用得当,自主交易非常有用,但很容易误用它们。这种情况 - 发生异常或回滚时的持久性日志记录 - 是它们的主要用例。但一般情况下,请谨慎使用:滥用自治事务很容易,最终导致数据库损坏。有更多信息in the Oracle documentation。
答案 2 :(得分:0)
DECLARE
部分中的错误引发不会由该块的EXCEPTION
部分处理。因此,在BEGIN
即
DECLARE
DBCID INT;
CNT INT;
BEGIN
DBCID := 'xxx';
...
EXCEPTION
WHEN OTHERS THEN
... -- The assignment will be caught here
END;