sql >> Databasteknik >  >> RDS >> Oracle

CASE och COALESCE kortslutningsutvärdering fungerar med sekvenser i PL/SQL men inte i SQL

För PL/SQL försäkrar Oracle att den kommer att använda kortslutningsutvärdering:

Från:2 PL/SQL Language Fundamentals

När du använder nextval i SQL-kod har vi en annan situation.

Först och främst måste vi komma ihåg att currval och nextval är pseudokolumner:

Från:3 Pseudocolumns .

Frågan är nu:varför Oracle utvärderar nextval ? eller är detta beteende angivet någonstans?

Från:Sequence Pseudocolumns

Ditt fall är helt klart "1. En SELECT-sats på toppnivå", men det betyder inte att kortslutningslogiken inte är på plats, utan bara att nextval utvärderas alltid.

Om du är intresserad av kortslutningslogiken är det bättre att ta bort nextval från ekvationen.

En fråga som denna utvärderar inte underfrågan:

select 6 c
  from dual
where  'a' = 'a' or 'a' = (select dummy from dual) 

Men om du försöker göra något liknande med coalesce eller case vi kommer att se att Oracle Optimizer bestämmer sig för att köra underfrågorna:

select 6 c
  from dual
where  'a' = coalesce('a', (select dummy from dual) )

Jag skapade kommenterade tester i denna demo i SQLFiddle för att visa detta.

Det ser ut som att Oracle endast tillämpar kortslutningslogiken om med ELLER-villkor, men med coalesce och case den måste utvärdera alla grenar.

Jag tror att dina första tester i PL/SQL visar att coalsce och case använd en kortslutningslogik i PL/SQL, som Oracle säger. Ditt andra test, inklusive sekvensen i SQL-satser, visar att i så fall nextval utvärderas ändå, även om resultatet inte används, och det dokumenterar Oracle också.

Att sätta ihop de två sakerna ser lite udda ut, eftersom coalesce och case beteende verkar vara riktigt inkonsekvent för mig också, men vi måste också komma ihåg att implementeringen av den logiken är implementeringsberoende (här är min källa )



  1. Förstå Android.coms självstudie för att spara data i SQL-databaser

  2. Ersätt kommatecken med nyrad och skriv till textfil

  3. MySQL exempeldatabas

  4. Doctrine Query Language få max/senaste raden per grupp