Oracle Select Works,Update不同,WHERE子句相同

时间:2013-06-21 19:32:32

标签: oracle select sql-update

最终更新:

事实证明,无论如何,这不是一个错误。隐藏在函数调用的深处是一个异常处理程序,它混淆了一条错误消息,表明该函数正在发生变异。处理程序隐藏它并导致函数返回本质上是有效值的函数。这次是我们的。 :)

原帖:

首先,这更像是一种好奇心,因为我已经解决了PL / SQL块的问题。但是,我和我的任何同事都无法弄清楚这个更新是行不通的。有没有人有任何想法?

我正在尝试使用适当的值更新新列。以前,记录的状态是使用按需计算状态的函数确定的,我们只是将其转换为使用专用表,允许存储状态并提高未来的灵活性。

以下选项效果很好 - 它提取了14条记录:

select * 
from QUERY_TABLE QT1
where QT1.P_ID in
  (select QT2.P_ID opi
    from QUERY_TABLE QT2
    where F_GET_STATUS(QT2.FUNC_VAL_1, 
      (select RT.FUNC_VAL_2 from RELATED_TABLE RT where RT.RELKEY = QT2.RELKEY)) = 'Value');

但是,以下更新使用相同的WHERE子句更新0条记录:

update QUERY_TABLE QT1
set QT1.STAT_ID = 1
where QT1.P_ID in
  (select QT2.P_ID opi
    from QUERY_TABLE QT2
    where F_GET_STATUS(QT2.FUNC_VAL_1, 
      (select RT.FUNC_VAL_2 from RELATED_TABLE RT where RT.RELKEY = QT2.RELKEY)) = 'Value');

不确定它是否有用,但下面的PL / SQL块可以正常处理更新:

begin
for x in (
  select QT2.P_ID opi
    from QUERY_TABLE QT2
    where F_GET_STATUS(QT2.FUNC_VAL_1, 
      (select RT.FUNC_VAL_2 from RELATED_TABLE RT where RT.RELKEY = QT2.RELKEY)) = 'Value')

loop
  update QUERY_TABLE QT1
  set QT1.STAT_ID = 1
  where P_ID = x.opi;
  end loop;
end;
/

我使用架构所有者和具有相应权限的其他用户执行了更新。表格上没有触发器使更新无效。该函数没有做任何奇怪的事情,并且函数和更新不会相互吞噬(它是一个全新的列 - 函数在语法上独立于列的值)。它不会给出任何错误消息 - 它只会更新0列。

更新1 对于那些可能遇到同样问题的人,我们已经联系了Oracle,事实证明这是一个新的错误。它已被记录为错误17015253:在子查询中使用功能的更新语句不会更新行,但我还没有在知识库中看到它。

2 个答案:

答案 0 :(得分:1)

我的经理很棒!!她建议加入:
pragma autonomous_transaction;
在函数体中的'is'之后会解决问题 有关详细信息,请参阅http://docs.oracle.com/cd/B28359_01/appdev.111/b28370/autotransaction_pragma.htm


功能xyz(...)
  return varchar2
  是
  pragma autonomous_transaction;
  varchar2(10);
  。
  。
  。
开始
 。
 。
 。
 返回一些东西;
结束xyz​​;

答案 1 :(得分:0)

就是这个问题的答案 - 函数中的异常处理程序混淆了一条错误消息,通知我们该函数正在发生变异。这使得它看起来好像函数和语法有效。