我们最近已从Oracle 10升级到Oracle
11.2。升级后,我开始看到由函数而不是触发器引起的变异表错误(我从未遇到过)。这是旧的代码,可以在Oracle的早期版本中使用。
这是导致错误的情况:
create table mutate (
x NUMBER,
y NUMBER
);
insert into mutate (x, y)
values (1,2);
insert into mutate (x, y)
values (3,4);
我创建了两行。现在,我将通过调用以下语句将行加倍:
insert into mutate (x, y)
select x + 1, y + 1
from mutate;
严格来说,复制该错误不是必须的,但稍后对我的演示很有帮助。因此,表的内容现在看起来像这样:
X,Y
1,2
3,4
2,3
4,5
一切都很好。现在是有趣的部分:
create or replace function mutate_count
return PLS_INTEGER
is
v_dummy PLS_INTEGER;
begin
select count(*)
into v_dummy
from mutate;
return v_dummy;
end mutate_count;
/
我创建了一个查询表并返回计数的函数。现在,我将其与INSERT语句结合起来:
insert into mutate (x, y)
select x + 2, y + 2
from mutate
where mutate_count() = 4;
结果?这个错误:
ORA-04091: table MUTATE is mutating, trigger/function may not see it
ORA-06512: at "MUTATE_COUNT", line 6
所以我知道是什么原因导致了错误,但是我对 为什么 感到好奇。Oracle是否不执行SELECT,检索结果集, 然后
对这些结果进行批量插入?如果在查询完成之前就已经插入了记录,我只会期望发生变异表错误。但是,如果Oracle这样做,先前的声明就不会:
insert into mutate (x, y)
select x + 1, y + 1
from mutate;
开始无限循环?
更新:
通过Jeffrey的链接,我在Oracle文档中发现了这一点:
默认情况下,Oracle保证语句级别的读取一致性。单个查询返回的数据集相对于单个时间点是一致的。
作者在他的帖子中也发表了评论:
有人可能会争辩说,为什么Oracle对于出现在SQL语句中的重复函数调用不保证这种“语句级读取一致性”。就我而言,它可能被认为是一个错误。但这就是目前的工作方式。
我是否假定Oracle 10和11版本之间的行为已更改,这是正确的吗?
首先,
insert into mutate (x, y)
select x + 1, y + 1
from mutate;
不启动无限循环,因为查询将看不到插入的数据-仅显示语句开始时已存在的数据。新行仅对后续语句可见。
这很好地解释了这一点:
当Oracle退出当前正在执行update语句的SQL引擎并调用该函数时,则此函数-就像行后更新触发器一样-
会看到执行更新过程中存在的EMP中间状态陈述。这意味着函数调用的返回值在很大程度上取决于行被更新的顺序。
怎么了: 我有多个对象保存在一个arraylist中,该arraylist保存在一个gson字符串中。 我更改对象的类(以包含更多变量和getter/setter方法) 现在我在尝试加载较旧的对象(保存在步骤1中)时遇到错误 错误消息: 谢谢你的帮助!
当我试图运行下面的代码时,每次我都得到错误“org.openqa.selenium.timeoutexception:Expected condition failed:waiting for visibility of element Locited by by.xpath”,我不确定xpate会是什么,请有人帮助我为登录应用程序创建自动化测试用例。 Java: HTML:
我尝试在Gradle上创建IntelliJ插件构建。这是我对它的GitHub回购https://GitHub.com/vladimirkozhaev/testgradleIntellijPlugin Ide是IntelliJ Ide 我错在哪里?相同版本的插件,但基于IDE运行良好
问题内容: 我正在使用以下方法从webapi捕获数据: 对于某些请求,这会由于HeapSize太小而导致OutOfMemoryError: 我已经从正常的String操作(如StringBuilder)换成了StringBuilder,但这没有帮助。我怎么解决这个问题?通过isnt作为其Android应用程序的一个选项来增加最大堆大小。 问题答案: 一种解决方案是将要下载的内容持久保存到存储中。