Oracle
 sql >> Datenbank >  >> RDS >> Oracle

Oracle SQL:Verstehen Sie das Verhalten von SYS_GUID(), wenn es in einer Inline-Ansicht vorhanden ist?

Die Dokumentation gibt einen Grund dafür an, warum Sie möglicherweise eine Diskrepanz sehen (Hervorhebung von mir):

Achtung:

Da SQL eine deklarative und keine imperative (oder prozedurale) Sprache ist, können Sie nicht wissen, wie oft eine von einer SQL-Anweisung aufgerufene Funktion ausgeführt wird – selbst wenn die Funktion in PL/SQL geschrieben ist, einer imperativen Sprache. Wenn Ihre Anwendung erfordert, dass eine Funktion eine bestimmte Anzahl von Malen ausgeführt wird, rufen Sie diese Funktion nicht von einer SQL-Anweisung aus auf. Verwenden Sie stattdessen einen Cursor.

Wenn Ihre Anwendung beispielsweise erfordert, dass für jede ausgewählte Zeile eine Funktion aufgerufen wird, öffnen Sie einen Cursor, wählen Sie Zeilen aus dem Cursor aus und rufen Sie die Funktion für jede Zeile auf. Diese Technik garantiert, dass die Anzahl der Aufrufe der Funktion der Anzahl der vom Cursor abgerufenen Zeilen entspricht.

Grundsätzlich gibt Oracle nicht an, wie oft eine Funktion innerhalb einer SQL-Anweisung aufgerufen wird:Dies kann unter anderem von der Version, der Umgebung und dem Zugriffspfad abhängen.

Es gibt jedoch Möglichkeiten, das Umschreiben von Abfragen einzuschränken, wie im Kapitel Entschachtelung von verschachtelten Unterabfragen erläutert:

Beim Aufheben der Verschachtelung von Unterabfragen wird der Hauptteil der Unterabfrage entschachtelt und mit dem Hauptteil der Anweisung zusammengeführt, die sie enthält, sodass der Optimierer sie zusammen berücksichtigen kann, wenn er Zugriffspfade und Verknüpfungen auswertet. Der Optimierer kann die meisten Unterabfragen entschachteln, mit einigen Ausnahmen . Zu diesen Ausnahmen gehören hierarchische Unterabfragen und Unterabfragen, die eine ROWNUM-Pseudospalte, einen der Mengenoperatoren, eine verschachtelte Aggregatfunktion oder einen korrelierten Verweis auf einen Abfrageblock enthalten, der nicht der unmittelbar äußere Abfrageblock der Unterabfrage ist.

Wie oben erklärt, können Sie ROWNUM verwenden Pseudo-Spalte, um zu verhindern, dass Oracle eine Unterabfrage entschachtelt:

SQL> WITH data AS (SELECT SYS_GUID() uuid FROM DUAL WHERE ROWNUM >= 1)
  2  SELECT uuid, uuid FROM data;

UUID                             UUID
-------------------------------- --------------------------------
1ADF387E847F472494A869B033C2661A 1ADF387E847F472494A869B033C2661A