Oracle
 sql >> Teknologi Basis Data >  >> RDS >> Oracle

klausa persatuan di sql

Jawaban ini mungkin sedikit bertele-tele...

Oracle sangat pilih-pilih dengan operasi yang ditetapkan. Setiap kolom harus memiliki tipe data yang sama dengan yang terkait di kueri kedua, ketiga, dll.

Saya berpikir kueri kedua Anda gagal karena Oracle mengevaluasi to_number() sebagai nomor sebelumnya untuk melakukan union tetapi mengevaluasinya untuk "null-ness" setelah . Kueri pertama Anda berhasil karena nilai pertama telah dievaluasi untuk "null-ness" dan kemudian union terjadi. Ini menyiratkan bahwa urutan evaluasi adalah:

  1. fungsi pilihan pertama
  2. Pilih tipe data pertama
  3. fungsi pilihan kedua
  4. serikat
  5. kedua pilih tipe data

Saya akan mencoba membuktikan ini selangkah demi selangkah, tetapi saya tidak yakin itu akan menjadi bukti yang mutlak.

Kedua pertanyaan berikut

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

akan gagal dengan kesalahan berikut karena tidak ada konversi implisit yang terjadi.

Namun, kedua hal berikut akan berhasil

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

Jika kita memilih dump dari dua pertanyaan ini, berikut ini akan dikembalikan:

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

Seperti yang Anda lihat, kolom memiliki tipe data yang berbeda . Kueri pertama, dengan karakter, mengembalikan char dan yang kedua mengembalikan angka, tetapi urutannya telah dibalik, dengan select second kedua datang lebih dulu.

Terakhir, jika kita melihat dump dari kueri pertama Anda

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>

Anda dapat melihat dump(to_number(null)) adalah nol; tapi varchar2 bukan char dikembalikan, karena ini adalah tipe data kolom Anda. Sangat menarik untuk dicatat bahwa urutan pernyataan yang dikembalikan belum dibalik dan jika Anda membuat kueri ini sebagai tabel, kedua kolom akan menjadi varchar2 .

Saat memutuskan tipe data kolom dalam kueri pemilihan, Oracle mengambil tipe data pertama yang diketahui dan kemudian menggunakannya untuk menghitung tipe data keseluruhan. Inilah sebabnya mengapa pertanyaan di mana select pertama adalah null jika barisnya dibalik.

Kueri pertama Anda berhasil karena pilihan pertama, select ename,to_number(null) from emp , "menggambarkan" seperti apa set hasil itu nantinya. |varchar2|null| . Kueri kedua kemudian menambahkan, |varchar2|varchar2| , yang tidak menyebabkan masalah.

Kueri kedua Anda gagal karena yang pertama pilih select ename,to_number(null) from emp "menggambarkan" hasil yang ditetapkan sebagai varchar2, null . Namun, Anda kemudian mencoba menambahkan angka nol dan varchar2 di union .

Lompatan keyakinan di sini adalah bahwa Oracle memutuskan bahwa to_number(null) adalah angka sebelumnya ke union dan tidak mengevaluasinya untuk "null-ness" sampai setelahnya. Saya tidak benar-benar tahu bagaimana menguji apakah ini benar-benar terjadi karena Anda tidak dapat membuat objek dengan null kolom dan seperti yang Anda perhatikan, Anda juga tidak dapat memilihnya.

Karena saya tidak dapat membuktikan sesuatu yang dilarang Oracle, saya akan mencoba untuk bukti empiris. Pertimbangkan hasil (atau kesalahan) dari kueri berikut.

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

Mereka tampaknya menunjukkan bahwa to_char dan to_number , tidak peduli apakah itu dilakukan pada null secara implisit mendefinisikan tipe data yang kemudian dievaluasi untuk kesesuaiannya dalam union , sebelum evaluasi mereka untuk "null-ness"

Penjelasan ini juga akan mencakup coalesce masalah sebagai to_number(null) adalah angka sebelum itu nol.




  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. memanggil prosedur tersimpan Oracle di R - bagaimana cara mendapatkan hasil yang ditetapkan?

  2. Mengatur Timeout Jaringan untuk koneksi JDBC

  3. Menghubungkan Oracle ke SQL Server dari Windows

  4. Cara mendapatkan Nilai Kunci sebagai hasil dari kolom Oracle JSON menggunakan JSON_TABLE

  5. menambahkan hari kerja di Oracle sql