Oracle
 sql >> база данни >  >> RDS >> Oracle

клауза съюз в sql

Този отговор може да е малко неразбираем...

Oracle е много придирчив към множество операции. Всяка колона трябва да има същия тип данни като съответните във втората, третата и т.н. заявки.

Аз мисля втората ви заявка е неуспешна, защото Oracle оценява to_number() като номер преди за извършване на union но го оценява за "нулевост" след . Първата ви заявка е успешна, защото първата стойност е оценена за „нулевост“ и след това union възниква. Това означава, че редът на оценяване е:

  1. Първи избрани функции
  2. Първи избор на типове данни
  3. Втори избор на функции
  4. съюз
  5. Втори избран тип данни

Ще се опитам да докажа това стъпка по стъпка, но не съм сигурен, че ще бъде абсолютно доказателство.

И двете следните заявки

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

ще се провали със следната грешка, тъй като не се извършва имплицитно преобразуване.

И двете обаче ще успеят

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

Ако изберем dump от тези две заявки се връща следното:

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

Както можете да видите, колоните имат различни типове данни . Първата заявка, със знак, връща char и вторият връща число, но редът е обърнат, с втория select на първо място.

И накрая, ако разгледаме dump от първото ви запитване

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>

Можете да видите този dump(to_number(null)) е нула; но varchar2 не е char се връща, защото това е типът данни на вашата колона. Интересно е да се отбележи, че редът на върнатите изрази не е обърнат и че ако създадете тази заявка като таблица, и двете колони ще бъдат varchar2 .

Когато определя типа данни на колона в заявка за избор, Oracle взема първия известен тип данни и след това го използва, за да изчисли общия тип данни. Това би било причината заявките, при които първият select беше нула, ако редовете им бяха обърнати.

Първата ви заявка е успешна, защото първото изберете, select ename,to_number(null) from emp , "описва" как ще изглежда наборът от резултати. |varchar2|null| . След това втората заявка добавя |varchar2|varchar2| , което не създава проблеми.

Втората ви заявка е неуспешна, защото първата изберете select ename,to_number(null) from emp "описва" резултатния набор като varchar2, null . След това обаче се опитвате да добавите нулево число и varchar2 в union .

Скокът на вярата тук е, че Oracle решава, че to_number(null) е число преди към union и не го оценява за "нулевост" до след това. Наистина не знам как да тествам дали това наистина се случва, тъй като не можете да създадете обект с null и както забелязахте, вие също не можете да го изберете.

Тъй като не мога да докажа нещо, което Oracle забранява, ще опитам за емпирични доказателства. Обмислете резултатите (или грешките) от следните заявки.

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

Те изглежда демонстрират, че to_char и to_number , без значение дали се изпълняват върху null имплицитно дефинират тип данни, който след това се оценява за неговата пригодност в union , преди оценката им за „нулевост“

Това обяснение ще обхване и coalesce проблем като to_number(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. Подчертаването не работи в клауза като оракул

  2. събира информация за dba_users в база данни на Oracle, когато е свързан като потребител

  3. Продължавайте да получавате ORA-00933:SQL командата не е приключила правилно

  4. Извикване на съхранена процедура с друга в Oracle

  5. Създайте списък с всички месеци от колона с дата в ORACLE SQL