Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/oracle/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oracle存储过程-如果未捕获,是否会引发应用程序错误禁用该过程?_Oracle - Fatal编程技术网

Oracle存储过程-如果未捕获,是否会引发应用程序错误禁用该过程?

Oracle存储过程-如果未捕获,是否会引发应用程序错误禁用该过程?,oracle,Oracle,我在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'

我在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 webservice(用C#编写)


问题是,一旦遇到错误,它似乎就卡住了。即使我手动将表中的状态更新为Y,并且看到它确实更新了,当我再次运行.NET服务时,它也会再次给我错误。但是,如果我再次运行创建或替换存储过程的SQL,然后运行webservice,它就不再“卡住”。或者如果我只是再次编译SP,这会修复它。有人知道这可能是什么吗?

在这种情况下,你不必提出异常,除非你真的想;您可以对更新进行编码,以便在状态为不需要的值之一时不会执行任何操作:

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;
这几乎肯定比执行
选择计数(*)…
(速度可能非常慢)然后转身执行
更新要快


共享和享受。

不,在存储过程中引发异常不会导致Oracle“卡住”。但是异常将返回给调用者,调用者将需要适当地处理异常,例如,回滚当前事务并关闭连接(或将其返回到连接池)


不清楚为什么重新编译存储过程会导致应用程序“不稳定”。提供的信息不足以确切解释您正在观察的行为。(正如Justin在他的评论中指出的,有几种可能性(事务隔离级别、未提交的事务、隐式提交、缓存的结果集等)

假设代码再次调用过程(即,它不会无意中缓存先前的结果),如果再次抛出错误,则至少有一行的
状态为0、P或N,并带有两个键。批处理(或手动更新)没有更新每一行,或者您的更新不可见,这可能是因为更新尚未提交,或者是因为您的代码的事务隔离级别已设置为可序列化。很难猜测,因为您没有发布可复制的测试用例。@Justin Cave,如果是因为行没有真正更新,则重新生成测试用例存储过程无法修复它。重新编译代码可以解决代码无法看到更新的问题(因为它隐式提交了您正在进行的更改,或者因为它导致代码使用可序列化隔离级别启动新事务)。它还可能触发应用程序停止缓存结果。这是事务隔离级别