Ta odpowiedź może być nieco chaotyczna...
Oracle jest bardzo wybredny z ustawionymi operacjami. Każda kolumna musi mieć ten sam typ danych, co odpowiadające jej w drugim, trzecim itd. zapytaniu.
myślę drugie zapytanie kończy się niepowodzeniem, ponieważ Oracle ocenia to_number()
jako liczba przed do wykonania union
ale ocenia go jako „nullness” po . Twoje pierwsze zapytanie powiodło się, ponieważ pierwsza wartość została oceniona pod kątem „null-ness”, a następnie union
występuje. Oznacza to, że kolejność oceny to:
- Pierwszy wybór funkcji
- Pierwszy wybór typów danych
- Drugie wybrane funkcje
- związek
- Drugi wybór typów danych
Spróbuję udowodnić to krok po kroku, ale nie jestem pewien, czy będzie to absolutny dowód.
Oba poniższe zapytania
select 1 from dual union select '1' from dual;
select '1' from dual union select 1 from dual;
zakończy się niepowodzeniem z następującym błędem, ponieważ nie zachodzi niejawna konwersja.
Jednak obie następujące czynności odniosą sukces
select null from dual union select '1' from dual;
select null from dual union select 1 from dual;
Jeśli wybierzemy dump
z tych dwóch zapytań zwracane jest następujące:
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
Jak widać kolumny mają różne typy danych
. Pierwsze zapytanie ze znakiem zwraca char
a drugi zwraca liczbę, ale kolejność została odwrócona, a drugi select
pierwszeństwo.
Na koniec, jeśli spojrzymy na dump
pierwszego zapytania
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>
Możesz zobaczyć, że dump(to_number(null))
jest zerowy; ale varchar2
nie char
jest zwracany, ponieważ jest to typ danych Twojej kolumny. Warto zauważyć, że kolejność zwracanych instrukcji nie została odwrócona i jeśli utworzysz to zapytanie jako tabelę, obie kolumny będą varchar2
.
Decydując o typie danych kolumny w zapytaniu wybierającym, Oracle bierze pierwszy znany typ danych, a następnie używa go do obliczenia ogólnego typu danych. To dlatego zapytania, w których pierwszy select
było null, a ich wiersze były odwrócone.
Twoje pierwsze zapytanie powiodło się, ponieważ pierwsze select, select ename,to_number(null) from emp
, „opisuje” wygląd zestawu wyników. |varchar2|null|
. Drugie zapytanie następnie dodaje, |varchar2|varchar2|
, co nie sprawia żadnych problemów.
Drugie zapytanie kończy się niepowodzeniem, ponieważ pierwsze wybiera select ename,to_number(null) from emp
"opisuje" zestaw wyników jako varchar2, null
. Jednak następnie próbujesz dodać liczbę null i varchar2 w union
.
Skok wiary polega na tym, że Oracle decyduje, że to_number(null)
jest liczbą przed do union
i nie oceniać go pod kątem „nullness” aż do później. Naprawdę nie wiem, jak sprawdzić, czy tak się dzieje, ponieważ nie można utworzyć obiektu z null
kolumna i jak zauważyłeś, nie możesz jej również wybrać.
Ponieważ nie mogę udowodnić czegoś, czego Oracle nie dopuszcza, postaram się o dowody empiryczne. Rozważ wyniki (lub błędy) następujących zapytań.
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
Zdają się demonstrować, że to_char
i to_number
, bez względu na to, czy są wykonywane na wartości null, niejawnie zdefiniuj typ danych, który jest następnie oceniany pod kątem jego przydatności w union
, przed ich oceną pod kątem „nullness”
To wyjaśnienie obejmowałoby również coalesce
problem jako to_number(null)
to liczba przed to jest null.