ドキュメントには、不一致が見られる理由が記載されています(私の強調):
注意:
SQLは命令型(または手続き型)言語ではなく宣言型言語であるため、SQLステートメントによって呼び出された関数が何回実行されるかを知ることはできません —関数が命令型言語であるPL / SQLで記述されている場合でも、アプリケーションで関数を特定の回数実行する必要がある場合は、SQL文からその関数を呼び出さないでください。代わりにカーソルを使用してください。
たとえば、アプリケーションで選択した行ごとに関数を呼び出す必要がある場合は、カーソルを開き、カーソルから行を選択して、行ごとに関数を呼び出します。この手法により、関数の呼び出し数がカーソルからフェッチされた行数になることが保証されます。
基本的に、Oracleは、SQLステートメント内で関数が呼び出される回数を指定しません。リリース、環境、アクセスパスなどの要因に依存する場合があります。
ただし、ネストされたサブクエリのネスト解除の章で説明されているように、クエリの書き換えを制限する方法があります。
Subquery unnestingは、サブクエリの本体をネスト解除して、それを含むステートメントの本体にマージします。これにより、オプティマイザは、アクセスパスと結合を評価するときにそれらを一緒に考慮することができます。オプティマイザは、一部の例外を除いて、ほとんどのサブクエリを検出できません。 。これらの例外には、階層サブクエリと、ROWNUM疑似列、集合演算子の1つ、ネストされた集計関数、またはサブクエリのすぐ外側のクエリブロックではないクエリブロックへの相関参照を含むサブクエリが含まれます。
上で説明したように、ROWNUM
を使用できます Oracleがサブクエリのネストを解除しないようにするための疑似列:
SQL> WITH data AS (SELECT SYS_GUID() uuid FROM DUAL WHERE ROWNUM >= 1)
2 SELECT uuid, uuid FROM data;
UUID UUID
-------------------------------- --------------------------------
1ADF387E847F472494A869B033C2661A 1ADF387E847F472494A869B033C2661A