sql >> Database >  >> RDS >> Oracle

CASE en COALESCE kortsluitingsevaluatie werkt met sequenties in PL/SQL maar niet in SQL

Voor PL/SQL verzekert Oracle dat het kortsluitevaluatie zal gebruiken:

Van:2 PL/SQL-taalbeginselen

Wanneer u de nextval . gebruikt in SQL-code hebben we een andere situatie.

Allereerst moeten we in gedachten houden dat currval en nextval zijn pseudokolommen:

Van:3 pseudokolommen .

De vraag is nu:waarom evalueert Oracle nextval ? of Wordt dit gedrag ergens vermeld?

Van:Opeenvolging pseudokolommen

Uw geval is duidelijk "1. Een SELECT-instructie op het hoogste niveau", maar het betekent niet dat de kortsluitlogica niet aanwezig is, maar alleen dat nextval wordt altijd geëvalueerd.

Als je geïnteresseerd bent in de kortsluitlogica, dan is het beter om de nextval te verwijderen uit de vergelijking.

Een zoekopdracht als deze evalueert de subquery niet:

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

Maar als je iets soortgelijks probeert te doen met coalesce of case we zullen zien dat de Oracle Optimizer besluit de subquery's uit te voeren:

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

Ik heb geannoteerde tests gemaakt in deze demo in SQLFiddle om dit te laten zien.

Het lijkt erop dat Oracle de kortsluitlogica alleen toepast als met OR-voorwaarde, maar met coalesce en case het moet alle takken evalueren.

Ik denk dat je eerste tests in PL/SQL laten zien dat coalsce en case gebruik een kortsluitlogica in PL/SQL, zoals Oracle stelt. Uw tweede test, inclusief de volgorde in SQL-statements, laat zien dat in dat geval de nextval wordt toch geëvalueerd, zelfs als het resultaat niet wordt gebruikt, en Oracle documenteert dat ook.

Het samenvoegen van de twee dingen ziet er een beetje vreemd uit, omdat coalesce en case gedrag lijkt mij ook echt inconsistent, maar we moeten ook in gedachten houden dat de implementatie van die logica implementatie-afhankelijk is (hier mijn bron )



  1. Hoe kan ik het integer-attribuut van een model toewijzen aan een string?

  2. Lock-in van databaseleveranciers voor MySQL of MariaDB vermijden

  3. Geo Django mac OS X

  4. Voeg twee tabellen samen in MySQL en retourneer slechts één rij van de tweede tabel