Di SQL Server, apa yang dimaksud dengan "SET ANSI_NULLS ON"?

92

Definisi tersebut mengatakan:

Ketika SET ANSI_NULLS ON, pernyataan SELECT yang menggunakan WHERE column_name = NULL mengembalikan baris nol bahkan jika ada nilai null di column_name. Pernyataan SELECT yang menggunakan WHERE nama_kolom <> NULL mengembalikan baris nol meskipun ada nilai bukan-null dalam nama_kolom.

Apakah ini berarti tidak ada null yang akan disertakan dalam kueri ini?

SELECT Region
FROM employees
WHERE Region = @region

Atau apakah ANSI_NULLhanya menyangkut pertanyaan seperti ini (di mana WHEREtermasuk kata tertentu NULL)?

SELECT Region
FROM employees
WHERE Region = NULL
Rodniko
sumber
1
Apakah jawabannya belum ada di paragraf ke-4 dari dokumentasi resmi tempat Anda menyalin paragraf pertama, yaitu: -> "SET ANSI_NULLS ON mempengaruhi perbandingan hanya jika salah satu operan perbandingan adalah variabel yaitu NULL atau NULL literal. Jika kedua sisi perbandingan adalah kolom atau ekspresi gabungan, setelan tidak akan memengaruhi perbandingan. "
pengguna1451111

Jawaban:

68

Ini berarti bahwa tidak ada baris akan dikembalikan jika @regionadalah NULL, bila digunakan dalam contoh pertama Anda, bahkan jika ada baris dalam tabel di mana RegionadalahNULL .

When ANSI_NULLSaktif (yang harus selalu Anda aktifkan, karena opsi untuk tidak mengaktifkannya akan dihapus di masa mendatang), operasi perbandingan apa pun di mana (setidaknya) salah satu operan NULLmenghasilkan nilai logika ketiga - UNKNOWN( sebagai lawan TRUEdan FALSE).

UNKNOWNnilai menyebar melalui operator boolean gabungan jika mereka belum diputuskan (misalnya ANDdengan FALSEoperan atau ORdengan TRUEoperan) atau negasi ( NOT).

The WHEREklausul digunakan untuk menyaring hasil set dihasilkan oleh FROMklausa, sehingga nilai keseluruhan dari WHEREklausul harus TRUEuntuk baris untuk tidak difilter. Jadi, jika suatu UNKNOWNdihasilkan oleh perbandingan apa pun, itu akan menyebabkan baris disaring.


@ user1227804 ini jawaban meliputi kutipan ini:

Jika kedua sisi perbandingan adalah kolom atau ekspresi gabungan, pengaturan tidak mempengaruhi perbandingan.

dari SET ANSI_NULLS *

Namun, saya tidak yakin poin apa yang coba dibuatnya, karena jika dua NULLkolom dibandingkan (misalnya dalam a JOIN), perbandingan masih gagal:

create table #T1 (
    ID int not null,
    Val1 varchar(10) null
)
insert into #T1(ID,Val1) select 1,null

create table #T2 (
    ID int not null,
    Val1 varchar(10) null
)
insert into #T2(ID,Val1) select 1,null

select * from #T1 t1 inner join #T2 t2 on t1.ID = t2.ID and t1.Val1 = t2.Val1

Kueri di atas mengembalikan 0 baris, sedangkan:

select * from #T1 t1 inner join #T2 t2 on t1.ID = t2.ID and (t1.Val1 = t2.Val1 or t1.Val1 is null and t2.Val1 is null)

Menampilkan satu baris. Jadi meskipun kedua operan adalah kolom, NULLtidak sama NULL. Dan dokumentasi untuk= tidak menjelaskan apa pun tentang operan:

Saat Anda membandingkan dua NULLekspresi, hasilnya bergantung pada ANSI_NULLSpengaturan:

Jika ANSI_NULLSdiatur ke ON, hasilnya adalah NULL1 , mengikuti konvensi ANSI bahwa nilai NULL(atau tidak diketahui) tidak sama dengan nilai lain NULLatau tidak diketahui.

Jika ANSI_NULLSdiset ke OFF, hasil dari NULLdibandingkan dengan NULLadalah TRUE.

Membandingkan NULLdengan non- NULLnilai selalu menghasilkan FALSE2 .

Namun, 1 dan 2 salah - hasil dari kedua perbandingan adalah UNKNOWN.


* Arti samar teks ini akhirnya ditemukan bertahun-tahun kemudian. Artinya sebenarnya, untuk perbandingan tersebut, setelan tidak berpengaruh dan selalu bertindak seolah-olah setelan AKTIF . Akan lebih jelas jika itu menyatakan bahwa SET ANSI_NULLS OFFitu adalah pengaturan yang tidak berpengaruh.

Damien_The_Tidak percaya
sumber
1
jadi jika saya mengerti Anda benar: itu mempengaruhi hasil dari frase "Where Region = @region" juga dan tidak hanya ketika saya menulis secara khusus "Where Region = null"?
Rodniko
7

Jika @Regionbukan sebuah nullnilai (katakanlah @Region = 'South') ia tidak akan mengembalikan baris di mana bidang Kawasan adalah nol, terlepas dari nilai ANSI_NULLS.

ANSI_NULLS hanya akan membuat perbedaan jika nilai @Regionis null, yaitu ketika query pertama Anda pada dasarnya menjadi yang kedua.

Dalam hal ini, ANSI_NULLS ON tidak akan mengembalikan baris apa pun (karena null = null akan menghasilkan nilai boolean yang tidak diketahui (alias null)) dan ANSI_NULLS OFF akan mengembalikan baris apa pun di mana bidang Region null (karena null = nullakan menghasilkan true)

SWeko
sumber
6

Jika ANSI_NULLS disetel ke "ON" dan jika kita menerapkan =, <> pada nilai kolom NULL saat menulis pernyataan pilih maka tidak akan mengembalikan hasil apa pun.

Contoh

create table #tempTable (sn int, ename varchar(50))

insert into #tempTable
values (1, 'Manoj'), (2, 'Pankaj'), (3, NULL), (4, 'Lokesh'), (5, 'Gopal')

SETEL ANSI_NULLS AKTIF

select * from #tempTable where ename is NULL -- (1 row(s) affected)
select * from #tempTable where ename = NULL -- (0 row(s) affected)
select * from #tempTable where ename is not NULL -- (4 row(s) affected)
select * from #tempTable where ename <> NULL -- (0 row(s) affected)

NONAKTIFKAN ANSI_NULLS

select * from #tempTable where ename is NULL -- (1 row(s) affected)
select * from #tempTable where ename = NULL -- (1 row(s) affected)
select * from #tempTable where ename is not NULL -- (4 row(s) affected)
select * from #tempTable where ename <> NULL -- (4 row(s) affected)
Pravat Behuria
sumber
2
+1 untuk menjadi SATU-SATUNYA jawaban yang dengan jelas membedakan antara WHERE X IS NULLdan WHERE X = NULL, dan bagaimana ANSI_NULLS memengaruhi hasilnya. Terlepas dari upaya para pemilih bawah yang terlalu bersemangat, INI harus menjadi jawaban yang diterima!
Riegardt Steyn
1
1 untuk menjelaskan menggunakan contoh, yang akan selalu lebih jelas dan lebih ringkas daripada kalimat yang panjang.
peter.aryanto
3

SETEL ANSI_NULLS AKTIF

IT Mengembalikan semua nilai termasuk nilai null dalam tabel

SET ANSI_NULLS nonaktif

Itu Berakhir ketika kolom berisi nilai null

Joseph Stalin
sumber
2
Tambahan apa yang ditambahkan jawaban ini ke jawaban yang sudah dinyatakan? Berhati-hatilah dalam menambahkan jawaban baru untuk pertanyaan lama - Mereka harus berisi penjelasan yang diperluas tentang solusi yang sudah diposting, atau memberikan wawasan baru - Dari Ulasan
Takarii
1

Saya kira hal utama di sini adalah:

Jangan pernah pengguna:

  • @anything = NULL
  • @anything <> NULL
  • @anything != null

Selalu gunakan:

  • @anything IS NULL
  • @anything IS NOT NULL
pengguna369142
sumber
0

Set ANSI NULLS OFF akan membuat perbandingan NULL = NULL menjadi true. TELUR:

        SET ANSI_NULLS OFF
        select * from sys.tables
        where principal_id = Null

akan mengembalikan beberapa hasil seperti yang ditampilkan di bawah ini: zcwInvoiceDeliveryType 744547 NULL zcExpenseRptStatusTrack 2099048 NULL ZCVendorPermissions 2840564 NULL ZCWOrgLevelClientFee 4322525 NULL

Meskipun kueri ini tidak akan memberikan hasil apa pun:

        SET ANSI_NULLS ON 
        select * from sys.tables
        where principal_id = Null
Pemecah masalah
sumber
0

https://docs.microsoft.com/en-us/sql/t-sql/statements/set-ansi-nulls-transact-sql

Ketika SET ANSI_NULLS ON, pernyataan SELECT yang menggunakan WHERE column_name = NULL mengembalikan baris nol bahkan jika ada nilai null di column_name. Pernyataan SELECT yang menggunakan WHERE column_name <> NULL mengembalikan baris nol meskipun ada nilai nonnull di column_name.

Misalnya

DECLARE @TempVariable VARCHAR(10)
SET @TempVariable = NULL

SET ANSI_NULLS ON
SELECT 'NO ROWS IF SET ANSI_NULLS ON' where    @TempVariable = NULL
-- IF ANSI_NULLS ON , RETURNS ZERO ROWS


SET ANSI_NULLS OFF
SELECT 'THERE WILL BE A ROW IF ANSI_NULLS OFF' where    @TempVariable =NULL
-- IF ANSI_NULLS OFF , THERE WILL BE ROW !
Prasanth VJ
sumber