9

次のようなものがあるとします。

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か?

4

1 に答える 1

16

カーソルから返される行のセットは、カーソルが開かれた時点で決定されます (ループOPENによって明示的または暗黙的に)。FORこの場合、削除した行はループに返されません。

通常、クエリは一度にすべて実行されるわけではありません。Oracle は、次の行セットをフェッチするのに十分なクエリを実行し、それらの行を PL/SQL VM に返し、さらに行をフェッチする要求が来るまで待機します。11g では、Oracle はBULK COLLECT一度に 100 行の暗黙的な処理を行うため、ループの 100 回の反復ごとに、返される行がなくなるまでクエリがさらに実行されます。マルチバージョン読み取りの一貫性により、Oracle は、コードの実行中に他のセッションが変更を行ってコミットしている場合でも、カーソルが開かれたときに存在していたデータを常に返します。

于 2013-03-01T15:42:22.420 に答える