Dokumentace uvádí důvod, proč můžete zaznamenat nesrovnalost (zdůrazňuji můj):
Upozornění:
Protože SQL je deklarativní jazyk, nikoli imperativní (nebo procedurální), nemůžete vědět, kolikrát se funkce vyvolaná příkazem SQL spustí —i když je funkce napsána v PL/SQL, imperativním jazyce. Pokud vaše aplikace vyžaduje, aby byla funkce provedena určitým počtem opakování, nevyvolávajte tuto funkci z příkazu SQL. Místo toho použijte kurzor.
Pokud například vaše aplikace vyžaduje volání funkce pro každý vybraný řádek, otevřete kurzor, vyberte řádky z kurzoru a zavolejte funkci pro každý řádek. Tato technika zaručuje, že počet volání funkce odpovídá počtu řádků načtených z kurzoru.
Oracle v zásadě nespecifikuje, kolikrát bude funkce volána uvnitř příkazu sql:může to záviset na verzi, prostředí, přístupové cestě a dalších faktorech.
Existují však způsoby, jak omezit přepisování dotazů, jak je vysvětleno v kapitole Rozpojení vnořených poddotazů:
Uvolnění poddotazu zruší vnoření a sloučí tělo poddotazu do těla příkazu, který jej obsahuje, což umožňuje optimalizátoru, aby je zvážil společně při vyhodnocování přístupových cest a spojení. Optimalizátor dokáže zrušit vnoření většiny poddotazů, až na některé výjimky . Tyto výjimky zahrnují hierarchické poddotazy a poddotazy, které obsahují pseudosloupec ROWNUM, jeden z operátorů sady, vnořenou agregační funkci nebo korelovaný odkaz na blok dotazu, který není bezprostředním vnějším blokem dotazu poddotazu.
Jak je vysvětleno výše, můžete použít ROWNUM
pseudo-sloupec, který zabrání Oracle ve zrušení vnoření poddotazu:
SQL> WITH data AS (SELECT SYS_GUID() uuid FROM DUAL WHERE ROWNUM >= 1)
2 SELECT uuid, uuid FROM data;
UUID UUID
-------------------------------- --------------------------------
1ADF387E847F472494A869B033C2661A 1ADF387E847F472494A869B033C2661A