Oracle
 sql >> Database >  >> RDS >> Oracle

Oracle SQL:comprensione del comportamento di SYS_GUID() quando presente in una vista in linea?

La documentazione fornisce un motivo per cui potresti notare una discrepanza (enfasi mia):

Attenzione:

Poiché SQL è un linguaggio dichiarativo, piuttosto che imperativo (o procedurale), non puoi sapere quante volte verrà eseguita una funzione invocata da un'istruzione SQL —anche se la funzione è scritta in PL/SQL, un linguaggio imperativo. Se l'applicazione richiede che una funzione venga eseguita un certo numero di volte, non richiamare quella funzione da un'istruzione SQL. Usa invece un cursore.

Ad esempio, se l'applicazione richiede che venga chiamata una funzione per ciascuna riga selezionata, aprire un cursore, selezionare le righe dal cursore e chiamare la funzione per ciascuna riga. Questa tecnica garantisce che il numero di chiamate alla funzione sia il numero di righe prelevate dal cursore.

Fondamentalmente, Oracle non specifica quante volte una funzione verrà chiamata all'interno di un'istruzione sql:potrebbe dipendere dal rilascio, dall'ambiente, dal percorso di accesso tra gli altri fattori.

Tuttavia, esistono modi per limitare la riscrittura delle query, come spiegato nel capitolo Annullamento dell'annidamento delle sottoquery nidificate:

L'annullamento dell'annidamento delle sottoquery annulla e unisce il corpo della sottoquery nel corpo dell'istruzione che lo contiene, consentendo all'ottimizzatore di considerarli insieme durante la valutazione dei percorsi di accesso e dei join. L'ottimizzatore può annullare l'annidamento della maggior parte delle sottoquery, con alcune eccezioni . Tali eccezioni includono sottoquery gerarchiche e sottoquery che contengono una pseudocolonna ROWNUM, uno degli operatori di insiemi, una funzione di aggregazione nidificata o un riferimento correlato a un blocco di query che non è il blocco di query esterno immediato della sottoquery.

Come spiegato sopra, puoi utilizzare ROWNUM pseudo-colonna per impedire a Oracle di annullare l'annidamento di una sottoquery:

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

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