Diese Antwort ist vielleicht etwas weitschweifig...
Oracle ist sehr wählerisch bei Mengenoperationen. Jede Spalte muss denselben Datentyp haben wie die entsprechenden Spalten in der zweiten, dritten usw. Abfrage.
Ich denke Ihre zweite Abfrage schlägt fehl, weil Oracle to_number()
auswertet als Zahl vorher um die union
durchzuführen wertet es aber auf "Nullheit" nach aus . Ihre erste Abfrage ist erfolgreich, da der erste Wert auf "Nullheit" und dann auf union
ausgewertet wurde tritt ein. Dies impliziert, dass die Auswertungsreihenfolge wie folgt lautet:
- 1. Funktionen auswählen
- 1. Datentypen auswählen
- Zweite Auswahlfunktionen
- Gewerkschaft
- 2. Datentypen auswählen
Ich werde versuchen, dies Schritt für Schritt zu beweisen, aber ich bin mir nicht sicher, ob es ein absoluter Beweis sein wird.
Die beiden folgenden Abfragen
select 1 from dual union select '1' from dual;
select '1' from dual union select 1 from dual;
schlägt mit dem folgenden Fehler fehl, da keine implizite Konvertierung stattfindet.
Die beiden folgenden werden jedoch erfolgreich sein
select null from dual union select '1' from dual;
select null from dual union select 1 from dual;
Wenn wir dump
Von diesen beiden Abfragen wird Folgendes zurückgegeben:
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
Wie Sie sehen können, haben die Spalten unterschiedliche Datentypen
. Die erste Abfrage mit einem Zeichen gibt ein char
zurück und der zweite gibt eine Zahl zurück, aber die Reihenfolge wurde umgekehrt, mit dem zweiten select
kommt zuerst.
Zuletzt, wenn wir uns dump
ansehen Ihrer ersten Anfrage
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>
Sie können diesen dump(to_number(null))
sehen ist Null; sondern ein varchar2
kein char
zurückgegeben wird, da dies der Datentyp Ihrer Spalte ist. Es ist interessant festzustellen, dass die Reihenfolge der zurückgegebenen Anweisungen nicht umgekehrt wurde und dass beide Spalten ein varchar2
wären, wenn Sie diese Abfrage als Tabelle erstellen würden .
Bei der Entscheidung über den Datentyp einer Spalte in einer Auswahlabfrage nimmt Oracle den ersten bekannten Datentyp und verwendet diesen dann zur Berechnung des Gesamtdatentyps. Dies wäre der Grund, warum die Abfragen das erste select
sind war null hatte ihre Zeilen umgekehrt.
Ihre erste Abfrage ist erfolgreich, weil der erste select, select ename,to_number(null) from emp
, "beschreibt", wie die Ergebnismenge aussehen wird. |varchar2|null|
. Die zweite Abfrage fügt dann hinzu, |varchar2|varchar2|
, was keine Probleme verursacht.
Ihre zweite Abfrage schlägt fehl, weil die erste select select ename,to_number(null) from emp
"beschreibt" die Ergebnismenge als varchar2, null
. Allerdings versuchen Sie dann, eine Nullzahl und eine varchar2 in union
einzufügen .
Der Vertrauensvorschuss hier ist, dass Oracle entscheidet, dass to_number(null)
ist eine Zahl vorher zur union
und erst danach auf "Nullheit" auswerten. Ich weiß nicht wirklich, wie ich testen soll, ob dies tatsächlich passiert, da Sie kein Objekt mit einem null
erstellen können Spalte und wie Sie bemerken, können Sie sie auch nicht auswählen.
Da ich etwas nicht beweisen kann, was Oracle nicht zulässt, versuche ich es mit empirischen Beweisen. Betrachten Sie die Ergebnisse (oder Fehler) der folgenden Abfragen.
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
Sie scheinen zu demonstrieren, dass to_char
und to_number
, unabhängig davon, ob sie auf Null ausgeführt werden, definieren implizit einen Datentyp, der dann in einer union
auf seine Eignung hin ausgewertet wird , vor ihrer Bewertung auf "Nullheit"
Diese Erklärung würde auch coalesce
abdecken Ausgabe als to_number(null)
ist eine Zahl vor es ist eine Null.