最终更新:
事实证明,无论如何,这不是一个错误。隐藏在函数调用的深处是一个异常处理程序,它混淆了一条错误消息,表明该函数正在发生变异。处理程序隐藏它并导致函数返回本质上是有效值的函数。这次是我们的。 :)
原帖:
首先,这更像是一种好奇心,因为我已经解决了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:在子查询中使用功能的更新语句不会更新行,但我还没有在知识库中看到它。
答案 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)
就是这个问题的答案 - 函数中的异常处理程序混淆了一条错误消息,通知我们该函数正在发生变异。这使得它看起来好像函数和语法有效。