3

最后更新:

事实证明,无论如何,这不是一个错误。隐藏在函数调用深处的是一个异常处理程序,它混淆了指示函数正在变异的错误消息。处理程序将其隐藏起来并导致函数返回本质上是有效值。所以这次就靠我们了。:)

原帖:

首先,这确实是一种好奇心,因为我已经使用 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:UPDATE STATEMENT WITH FUNCTION IN SUBQUERY DOES NOT UPDATE ROWS,尽管我在知识库中还没有看到它。

4

2 回答 2

1

我的经理很棒!!她建议通过添加:
pragma automatic_transaction;
在函数体中的“是”之后将解决问题。
有关详细信息,请参阅http://docs.oracle.com/cd/B28359_01/appdev.111/b28370/autotransaction_pragma.htm

前任。
函数 xyz (...)
  return varchar2
  is
   pragma automatic_transaction;
   varchar2(10);
   .
   .
   .
开始

.
.
  归还东西;
结束 xyz;

于 2013-07-16T15:10:41.983 回答
0

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

于 2013-07-03T19:20:29.387 回答