我在Oracle中有一个存储过程:
SELECT Count(*) INTO v_count_of_rows_bad FROM SCHMEA.TABLE WHERE
KEY1 = v_key1
AND KEY2 = v_key2
AND STATUS IN ('0', 'P', 'N');
IF v_count_of_rows_bad > 0 THEN
raise_application_error( -20001, 'Status is not ready' );
END IF;
目的是防止SP在状态为其中之一时更新记录。有一个批处理过程将针对行运行,并在完成时将状态更新为Y.只有在此之后才允许SP更新该行。 (我知道可能有更好的方法来做到这一点,但我坚持使用一些遗留的东西,另一个团队控制批处理过程。)
我没有在存储过程中捕获异常,而是使用它将文本“Status it not ready”传输到我正在调用该过程的.NET Web服务(用C#编写)。
问题是,一旦遇到错误,它似乎就会卡住。即使我手动将状态更新为表中的Y,并且看到它确实更新了,当我再次运行我的.NET服务时,它再次给我错误。但是,如果我再次运行创建或替换存储过程的SQL,那么运行webservice,它就不再“卡住”了。或者如果我只是再次编译SP,则修复它。有谁知道这可能是什么?
答案 0 :(得分:1)
不,在存储过程中引发异常并不会导致Oracle卡住"卡住"。但是异常将返回给调用者,调用者需要适当地处理异常,例如,ROLLBACK当前事务,并关闭连接(或将其返回到连接池。)
目前尚不清楚为什么重新编译存储过程会导致应用程序变得“松散”#34;。提供的信息不足以明确解释您正在观察的行为。 (正如Justin在他的评论中指出的那样,有几种可能性(事务隔离级别,未提交的事务,隐式提交,缓存的结果集等)。
答案 1 :(得分:0)
除非你真的想要,否则你不必在这种情况下提出异常;你可以只对UPDATE进行编码,这样如果状态是不合需要的值之一,它就不会做任何事情:
UPDATE A_SCHEMA.SOME_TABLE
SET SOME_COL = vVALUE,
SOME_OTHER_COL = vOTHER_VALUE,
ETC = vBLAH
WHERE KEY1 = v_key1 AND
KEY2 = v_key2 AND
STATUS NOT IN ('0', 'P', 'N');
如果您需要知道是否有任何行已更新,您可以使用%ROWCOUNT,如
IF SQL%ROWCOUNT > 0 THEN
DBMS_OUTPUT.PUT_LINE(SQL%ROWCOUNT || ' rows updated');
ELSE
DBMS_OUTPUT.PUT_LINE('No rows updated! Run! Run for your lives!!');
END IF;
这几乎肯定比执行SELECT COUNT(*)...
(速度可能非常慢)和然后转身并执行UPDATE
更快。
分享并享受。