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:
- Eerste geselecteerde functies
- Eerste geselecteerde datatypes
- 2e geselecteerde functies
- vereniging
- 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.