sql >> Database >  >> RDS >> Oracle

vakbondsclausule in sql

Dit antwoord is misschien een beetje ingewikkeld...

Oracle is erg kieskeurig met vaste operaties. Elke kolom moet hetzelfde gegevenstype hebben als de corresponderende in de tweede, derde enz. zoekopdrachten.

Ik denk uw tweede query mislukt omdat Oracle to_number() . evalueert als een getal vooraf tot het uitvoeren van de union maar evalueert het op "null-ness" na . Uw eerste zoekopdracht is geslaagd omdat de eerste waarde is geëvalueerd op "null-ness" en vervolgens op de union komt voor. Dit houdt in dat de volgorde van evaluatie is:

  1. Eerste geselecteerde functies
  2. Eerste geselecteerde datatypes
  3. 2e geselecteerde functies
  4. vereniging
  5. 2e geselecteerde datatypes

Ik zal proberen dit stap voor stap te bewijzen, maar ik weet niet zeker of dit een absoluut bewijs zal zijn.

Zowel de volgende vragen

select 1 from dual union select '1' from dual;
select '1' from dual union select 1 from dual;

zal mislukken met de volgende fout omdat er geen impliciete conversie plaatsvindt.

Beide volgende zullen echter slagen

select null from dual union select '1' from dual;
select null from dual union select 1 from dual;

Als we de dump van deze twee zoekopdrachten wordt het volgende geretourneerd:

SQL> select dump(a)
  2    from ( select null a from dual union select '1' from dual );

DUMP(A)
-------------------------------------------------------------------

Typ=96 Len=1: 49
NULL

SQL> select dump(a)
  2    from ( select null a from dual union select 1 from dual );

DUMP(A)
-------------------------------------------------------------------

Typ=2 Len=2: 193,2
NULL

Zoals u kunt zien, hebben de kolommen verschillende gegevenstypes . De eerste zoekopdracht, met een teken, retourneert een char en de tweede geeft een getal terug, maar de bestelling is omgedraaid, met de tweede select eerst komen.

Ten slotte, als we kijken naar dump van uw eerste vraag

SQL> select substr(dump(ename),1,35) a, substr(dump(loc),1,35) b
  2    from ( select ename,to_number(null) as loc from emp
  3            union
  4           select to_char(null),loc from dept
  5                  );

A                                   B
----------------------------------- -----------------------------------
Typ=1 Len=6: 104,97,104,97,104,97   NULL
NULL                                Typ=1 Len=6: 104,97,104,97,104,97

SQL>

Je kunt zien dat dump(to_number(null)) is niets; maar een varchar2 geen char wordt geretourneerd, omdat dit het gegevenstype van uw kolom is. Het is interessant om op te merken dat de volgorde van de geretourneerde instructies niet is omgekeerd en dat als u deze query als een tabel zou maken, beide kolommen een varchar2 zouden zijn .

Bij het bepalen van het gegevenstype van een kolom in een selectiequery neemt Oracle het eerste bekende gegevenstype en gebruikt dat vervolgens om het algemene gegevenstype te berekenen. Dit zou de reden zijn waarom de zoekopdrachten waarbij de eerste select was null hadden hun rijen omgekeerd.

Uw eerste zoekopdracht slaagt omdat de eerste selectie, select ename,to_number(null) from emp , "beschrijft" hoe de resultatenset eruit gaat zien. |varchar2|null| . De tweede query voegt dan toe:|varchar2|varchar2| , wat geen problemen oplevert.

Uw tweede zoekopdracht mislukt omdat de eerste select ename,to_number(null) from emp selecteert "beschrijft" de resultaatset als varchar2, null . U probeert dan echter een null-nummer en een varchar2 toe te voegen in de union .

De sprong in het diepe is dat Oracle besluit dat to_number(null) is een getal vooraf naar de union en pas daarna het op "null-ness" evalueren. Ik weet niet echt hoe ik moet testen of dit echt gebeurt, omdat je geen object kunt maken met een null kolom en zoals u opmerkt, kunt u deze ook niet selecteren.

Omdat ik iets niet kan bewijzen dat Oracle niet toestaat, zal ik proberen voor empirisch bewijs. Bekijk de resultaten (of fouten) van de volgende zoekopdrachten.

SQL> select 1 as a from dual union select to_number(null) from dual;

         A
----------
         1


SQL> select '1' as a from dual union select to_number(null) from dual;
select '1' as a from dual union select to_number(null) from dual
       *
ERROR at line 1:
ORA-01790: expression must have same datatype as corresponding expression


SQL> select 1 as a from dual union select to_char(null) from dual;
select 1 as a from dual union select to_char(null) from dual
       *
ERROR at line 1:
ORA-01790: expression must have same datatype as corresponding expression


SQL> select '1' as a from dual union select to_char(null) from dual;

A
-
1

Ze lijken aan te tonen dat to_char en to_number , ongeacht of ze worden uitgevoerd op een null, definieer impliciet een gegevenstype dat vervolgens wordt geëvalueerd op zijn geschiktheid in een union , voorafgaand aan hun evaluatie voor "null-ness"

Deze uitleg zou ook betrekking hebben op de coalesce probleem als de to_number(null) is een getal voor het is een nul.




  1. Hoe PostgreSQL upgraden met PostGIS?

  2. mysql-query met Yii-querybuilder

  3. Hoe installeer ik SQLcl op Windows?

  4. Een tabel maken op basis van een query en rijen die zijn opgehaald uit de select-instructie