Saya menulis Pernyataan T-SQL yang mirip seperti ini (yang asli terlihat berbeda tetapi saya ingin memberikan contoh mudah di sini):
SELECT first_name +
CASE last_name WHEN null THEN 'Max' ELSE 'Peter' END AS Name
FROM dbo.person
Pernyataan ini tidak memiliki kesalahan sintaksis apa pun, tetapi case-clause selalu memilih bagian ELSE - juga jika last_name adalah null. Tapi kenapa?
Yang ingin saya lakukan adalah menyatukan first_name dan last_name, tetapi jika last_name nol, seluruh nama menjadi nol:
SELECT first_name +
CASE last_name WHEN null THEN '' ELSE ' ' + last_name END AS Name
FROM dbo.person
Apakah Anda tahu di mana masalahnya?
COALESCE
pada dasarnya diterjemahkan secara internal menjadiCASE
. Masalah dengan CASE adalah yanglast_name
dievaluasi dua kali dan dapat menyebabkan efek samping lain - lihat artikel yang sangat bagus ini . Untuk menyelesaikan apa yang diminta, saya lebih suka pergi denganISNULL(' '+ last_name, '')
disebutkan dalam komentar di bawah.Bagian WHEN dibandingkan dengan ==, tetapi Anda tidak dapat benar-benar membandingkannya dengan NULL. Mencoba
sebagai gantinya atau COALESCE:
('' + last_name adalah NULL ketika last_name adalah NULL, jadi itu harus mengembalikan '' dalam kasus itu)
sumber
Ada banyak solusi tetapi tidak ada yang menjelaskan mengapa pernyataan aslinya tidak berfungsi.
Setelah kapan, ada pemeriksaan untuk kesetaraan, yang harus benar atau salah.
Jika satu atau kedua bagian dari perbandingan adalah nol, hasil perbandingan tersebut akan DIKETAHUI, yang diperlakukan sebagai false dalam struktur kasus. Lihat: https://www.xaprb.com/blog/2006/05/18/why-null-never-compares-false-to-anything-in-sql/
Untuk menghindari ini, Coalesce adalah cara terbaik.
sumber
Dengan kueri Anda, Anda juga dapat melakukan ini:
sumber
ISNULL(' '+ last_name, '')
untuk mencegah ruang redundan.Masalahnya adalah bahwa null tidak dianggap sama dengan dirinya sendiri, maka klausa tidak pernah cocok.
Anda perlu memeriksa null secara eksplisit:
sumber
mencoba:
Ini menambahkan spasi ke nama belakang, jika itu nol, seluruh ruang + nama belakang pergi ke NULL dan Anda hanya mendapatkan nama depan, jika tidak, Anda akan mendapatkan firts + spasi + nama belakang.
ini akan berfungsi selama pengaturan default untuk rangkaian dengan string nol diatur:
ini seharusnya tidak menjadi perhatian karena
OFF
mode akan hilang dalam versi SQl Server yang akan datangsumber
Masalahnya adalah bahwa NULL tidak dianggap sama dengan apa pun bahkan tidak dengan dirinya sendiri, tetapi bagian yang aneh adalah bahwa itu juga tidak sama dengan dirinya sendiri.
Pertimbangkan pernyataan berikut (yang ilegal BTW di SQL Server T-SQL tetapi valid dalam My-SQL, namun ini adalah apa yang ANSI tetapkan untuk null, dan dapat diverifikasi bahkan dalam SQL Server dengan menggunakan pernyataan kasus, dll.)
SELECT NULL = NULL -- Results in NULL
SELECT NULL <> NULL -- Results in NULL
Jadi tidak ada jawaban benar / salah untuk pertanyaan, sebaliknya jawabannya juga nol.
Ini memiliki banyak implikasi, misalnya dalam
WHEN NULL
kondisi )SELECT a + NULL -- Results in NULL
Seseorang dapat mengesampingkan perilaku ini dalam SQL Server dengan menentukan
SET ANSI_NULLS OFF
, namun ini TIDAK dianjurkan dan tidak boleh dilakukan karena dapat menyebabkan banyak masalah, hanya karena penyimpangan standar.(Sebagai catatan, di My-SQL ada opsi untuk menggunakan operator khusus
<=>
untuk perbandingan nol.)Sebagai perbandingan, dalam bahasa pemrograman umum null diperlakukan sebagai nilai reguler dan sama dengan dirinya sendiri, namun itu adalah nilai NAN yang juga tidak sama dengan dirinya sendiri, tetapi setidaknya mengembalikan 'salah' ketika membandingkannya dengan dirinya sendiri, (dan ketika memeriksa tidak sama dengan bahasa pemrograman yang berbeda, memiliki implementasi yang berbeda).
Perhatikan bahwa dalam bahasa-bahasa Basic (mis. VB dll.) Tidak ada kata kunci 'null' dan sebaliknya orang menggunakan kata kunci 'Nothing', yang tidak dapat digunakan dalam perbandingan langsung dan sebagai gantinya orang perlu menggunakan 'IS' seperti dalam SQL, namun sebenarnya sama dengan dirinya sendiri (saat menggunakan perbandingan tidak langsung).
sumber
sumber
Ketika Anda merasa frustrasi mencoba ini:
Coba yang ini sebagai gantinya:
LEN(ISNULL(last_Name,''))
mengukur jumlah karakter di kolom itu, yang akan menjadi nol apakah itu kosong, atau NULL, oleh karena ituWHEN 0 THEN
akan mengevaluasi ke true dan mengembalikan '' seperti yang diharapkan.Saya harap ini adalah alternatif yang bermanfaat.
Saya telah memasukkan test case ini untuk sql server 2008 dan di atasnya:
sumber
Jason mendapat kesalahan, jadi ini berfungsi ...
Adakah yang bisa mengkonfirmasi versi platform lainnya?
SQL Server:
MySQL:
Peramal:
sumber
Anda dapat menggunakan fungsi IsNull
jika satu kolom nol Anda akan mendapatkan char kosong
Kompatibel dengan Microsoft SQL Server 2008+
sumber
Gunakan fungsi CONCAT yang tersedia di SQL Server 2012 dan seterusnya.
sumber
Saya mencoba casting ke string dan menguji string dengan panjang nol dan berhasil.
sumber
NULL tidak sama dengan apa pun. Pernyataan kasus pada dasarnya mengatakan ketika nilai = NULL .. itu tidak akan pernah mengenai.
Ada juga beberapa prosedur tersimpan sistem yang ditulis secara salah dengan sintaks Anda. Lihat sp_addpullsubscription_agent dan sp_who2.
Seandainya saya tahu cara memberi tahu Microsoft tentang kesalahan itu karena saya tidak dapat mengubah sistem yang disimpan procs.
sumber