假设我有类似的东西:
CURSOR foo_cur IS
SELECT * FROM foo;
...
DELETE FROM foo WHERE bar=1;
FOR row IN foo_cur
LOOP
...
END LOOP;
如果我在打开游标之前删除行foo
,这些行仍然是游标结果的一部分吗?查询是否SELECT * FROM foo
在该行执行FOR row IN foo_cur
?
假设我有类似的东西:
CURSOR foo_cur IS
SELECT * FROM foo;
...
DELETE FROM foo WHERE bar=1;
FOR row IN foo_cur
LOOP
...
END LOOP;
如果我在打开游标之前删除行foo
,这些行仍然是游标结果的一部分吗?查询是否SELECT * FROM foo
在该行执行FOR row IN foo_cur
?
将从游标返回的行集在打开游标时确定(通过循环显式OPEN
或隐式)。FOR
在这种情况下,您删除的行将不会在您的循环中返回。
通常,查询不会一次全部执行。Oracle 执行足够多的查询以获取下一组行,将这些行返回给 PL/SQL VM,并等待直到请求到来以获取更多行。在 11g 中,Oracle 将一次隐式BULK COLLECT
执行 100 行,因此每 100 次循环迭代,查询将进一步执行,直到没有更多行返回。由于多版本读取一致性,Oracle 将始终将数据返回给您,即使在您的代码运行时其他会话正在进行更改并提交更改,当游标打开时仍然存在。