Oracle
 sql >> Baza danych >  >> RDS >> Oracle

klauzula unii w sql

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:

  1. Pierwszy wybór funkcji
  2. Pierwszy wybór typów danych
  3. Drugie wybrane funkcje
  4. związek
  5. 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.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Wykonywanie procedury składowanej Oracle w EntityFramework

  2. Jak wyłączyć wygaśnięcie hasła Oracle?

  3. Funkcja Oracle do porównywania ciągów w sposób nieuporządkowany

  4. Oracle 11g - pętla FOR, która wstawia do tabeli tylko dni tygodnia?

  5. Jak utworzyć zagnieżdżoną tabelę jako obiekt bazy danych w Oracle?