W SQL Server ANSI_NULLS
ustawienie pozwala określić, jak NULL
wartości są traktowane w zapytaniach.
Mówiąc dokładniej, pozwala określić zgodne z ISO zachowanie funkcji Equals (=
) i Nie równa się (<>
) operatory porównania, gdy są używane z NULL
wartości.
ANSI_NULLS
można ustawić na ON
lub OFF
. NULL
test, który zwraca prawdę z ANSI_NULLS OFF
może faktycznie zwrócić false z ANSI_NULLS ON
.
Może to być źródłem wielu nieporozumień, dlatego warto dokładnie zrozumieć, w jaki sposób ANSI_NULLS
Pracuje.
ANSI_NULLS
ustawienia można ustawić na poziomie bazy danych i na poziomie sesji. Jeśli ANSI_NULLS
ustawienie na poziomie sesji nie jest określone, SQL Server użyje dowolnego ANSI_NULLS
ustawienie jest stosowane do bieżącej bazy danych. Dlatego podczas pisania zapytań ad hoc można zastąpić ustawienie bazy danych własnym ustawieniem poziomu sesji.
Należy zauważyć, że sterownik ODBC SQL Server Native Client i dostawca SQL Server Native Client OLE DB dla SQL Server automatycznie ustawiają ANSI_NULLS
na ON
podczas łączenia. To ustawienie można skonfigurować w źródłach danych ODBC, w atrybutach połączenia ODBC lub we właściwościach połączenia OLE DB, które są ustawione w aplikacji przed nawiązaniem połączenia z wystąpieniem programu SQL Server.
Jak sprawdzić ustawienia ANSI_NULLS sesji
Możesz użyć SESSIONPROPERTY()
funkcja sprawdzania ANSI_NULLS
ustawienie dla bieżącej sesji.
SELECT SESSIONPROPERTY('ANSI_NULLS');
Wynik:
+--------------------+ | (No column name) | |--------------------| | 1 | +--------------------+
W tym przypadku ANSI_NULLS
ustawienie dla mojej sesji jest ON
.
Zero (0
) oznaczałoby, że jest wyłączone.
Jak zmienić ustawienia ANSI_NULLS sesji
Możesz ustawić ANSI_NULLS sesji na OFF
z następującym kodem:
SET ANSI_NULLS OFF;
Następnie ponowne sprawdzenie go da zero.
SELECT SESSIONPROPERTY('ANSI_NULLS');
Wynik:
+--------------------+ | (No column name) | |--------------------| | 0 | +--------------------+
Domyślna wartość dla SET ANSI_NULLS
jest OFF
. Jednak, jak wspomniano powyżej, sterownik ODBC SQL Server Native Client i dostawca SQL Server Native Client OLE DB dla SQL Server automatycznie ustawiają ANSI_NULLS
na ON
podczas łączenia.
Przykłady tego, jak ANSI_NULLS
Wpływa na zapytania
Oto kilka podstawowych przykładów demonstrujących różne wyniki, które można uzyskać, w zależności od wartości ANSI_NULLS
ustawienie.
Używają one SET ANSI_NULLS
aby przełączyć ANSI_NULLS
ustawienie dla bieżącej sesji.
ANSI_NULLS ON
SET ANSI_NULLS ON;
SELECT NULL
WHERE NULL = NULL;
Wynik:
(0 rows affected)
Kiedy ANSI_NULLS
jest ON
, wszystkie porównania z NULL
wartość oceniana na UNKNOWN
.
W tym przypadku nie możemy tak naprawdę powiedzieć, że NULL
równa się NULL
ponieważ każda wartość jest nieznana.
Dlatego dla powyższego zapytania nie są zwracane żadne wiersze.
ANSI_NULLS OFF
SET ANSI_NULLS OFF;
SELECT NULL
WHERE NULL = NULL;
Wynik:
+--------------------+ | (No column name) | |--------------------| | NULL | +--------------------+
Kiedy ANSI_NULLS
jest OFF
, porównania wszystkich danych z NULL
wartość oceniana na TRUE
jeśli wartość danych to NULL
.
Ta sama logika ma zastosowanie w przypadku korzystania z operatora Nie równa się (<>
).
Rozwińmy przykład tak, aby zawierał operator Nie równe (<>
), a także porównanie NULL
i inny niż NULL
wartość.
ANSI_NULLS ON
SET ANSI_NULLS ON;
SELECT NULL
WHERE NULL = NULL;
SELECT 'Not NULL'
WHERE NULL <> NULL;
SELECT NULL
WHERE 1 = NULL;
SELECT 'Not NULL'
WHERE 1 <> NULL;
Wynik:
(0 rows affected) (0 rows affected) (0 rows affected) (0 rows affected)
Zgodnie z oczekiwaniami dla żadnego z zapytań nie są zwracane żadne wiersze. Dzieje się tak, ponieważ NULL
wartości są traktowane jako UNKNOWN
wartość, gdy ANSI_NULLS
jest ON
.
ANSI_NULLS OFF
SET ANSI_NULLS OFF;
SELECT NULL
WHERE NULL = NULL;
SELECT 'Not NULL'
WHERE NULL <> NULL;
SELECT NULL
WHERE 1 = NULL;
SELECT 'Not NULL'
WHERE 1 <> NULL;
Wynik:
+--------------------+ | (No column name) | |--------------------| | NULL | +--------------------+ (1 row affected) (0 rows affected) (0 rows affected) +--------------------+ | (No column name) | |--------------------| | Not NULL | +--------------------+ (1 row affected)
Otrzymamy inny wynik, gdy ANSI_NULLS
jest OFF
.
W tym przypadku SQL Server nie traktuje NULL
jako UNKNOWN
. Określa, że NULL
jest w rzeczywistości równa NULL
.
Nie jest to zgodne ze standardem ANSI.
IS NULL
Predykat
Aby skrypt działał zgodnie z przeznaczeniem, niezależnie od ANSI_NULLS
opcja bazy danych lub ustawienie SET ANSI_NULLS
, użyj IS NULL
i IS NOT NULL
w porównaniach, które mogą zawierać wartości null
Oto, co się dzieje, gdy przepisujemy poprzedni przykład tak, aby używał IS NULL
i IS NOT NULL
.
ANSI_NULLS ON
SET ANSI_NULLS ON;
SELECT NULL
WHERE NULL IS NULL;
SELECT NULL
WHERE NULL IS NOT NULL;
SELECT 'Not NULL'
WHERE 1 IS NULL;
SELECT 'Not NULL'
WHERE 1 IS NOT NULL;
Wynik:
+--------------------+ | (No column name) | |--------------------| | NULL | +--------------------+ (1 row affected) (0 rows affected) (0 rows affected) +--------------------+ | (No column name) | |--------------------| | Not NULL | +--------------------+ (1 row affected)
ANSI_NULLS OFF
SET ANSI_NULLS OFF;
SELECT NULL
WHERE NULL IS NULL;
SELECT NULL
WHERE NULL IS NOT NULL;
SELECT 'Not NULL'
WHERE 1 IS NULL;
SELECT 'Not NULL'
WHERE 1 IS NOT NULL;
Wynik:
+--------------------+ | (No column name) | |--------------------| | NULL | +--------------------+ (1 row affected) (0 rows affected) (0 rows affected) +--------------------+ | (No column name) | |--------------------| | Not NULL | +--------------------+ (1 row affected)
Zgodnie z oczekiwaniami otrzymujemy ten sam wynik niezależnie od ANSI_NULLS
ustawienie.
Tabela porównawcza
Poniższa tabela przedstawia odmiany, które można uzyskać w zależności od wyrażenia logicznego i ANSI_NULLS
ustawienie.
Wyrażenie logiczne | WŁĄCZ ANSI_NULLS | WYŁĄCZ ANSI_NULLS |
---|---|---|
NULL =NULL | NIEZNANE | PRAWDA |
1 =NULL | NIEZNANE | FAŁSZ |
NULL <> NULL | NIEZNANE | FAŁSZ |
1 <> NULL | NIEZNANE | PRAWDA |
NULL> NULL | NIEZNANE | NIEZNANE |
1> NULL | NIEZNANE | NIEZNANE |
NULL TO NULL | PRAWDA | PRAWDA |
1 JEST NULL | FAŁSZ | FAŁSZ |
NULL NIE JEST NULL | FAŁSZ | FAŁSZ |
1 NIE JEST NULL | PRAWDA | PRAWDA |
Ustawianie ANSI_NULLS na poziomie bazy danych
Każda baza danych SQL Server ma ANSI_NULLS
ustawienie, które określa sposób porównywania z NULL
wartości są oceniane.
- Gdy ustawione na
ON
, porównania doNULL
wartość oceniana naUNKNOWN
. - Gdy ustawione na
OFF
, porównania wartości innych niż Unicode zNULL
wartość oceniana naTRUE
jeśli obie wartości sąNULL
.
Możesz zmienić to ustawienie w bazie danych za pomocą następującego kodu:
ALTER DATABASE CURRENT
SET ANSI_NULLS ON;
To ustawia ANSI_NULLS
na ON
dla bieżącej bazy danych. Możesz zamienić CURRENT
z nazwą bazy danych, jeśli jest to preferowane.
Możesz sprawdzić bieżące ustawienie za pomocą DATABASEPROPERTYEX()
funkcja.
SELECT DATABASEPROPERTYEX('Music','IsAnsiNullsEnabled');
Wynik:
1
Jak wspomniano, możesz zastąpić to ustawienie podczas pisania zapytań ad hoc, ustawiając je na poziomie sesji, tak jak to zrobiliśmy wcześniej.
Skoro jesteśmy przy tym temacie, powinienem wspomnieć, że bazy danych SQL Server mają również ANSI_NULL_DEFAULT
ustawienie. To ustawienie określa wartość domyślną NULL
lub NOT NULL
, kolumny lub typu zdefiniowanego przez użytkownika w środowisku CLR, dla którego dopuszczalność wartości null nie jest jawnie zdefiniowana w CREATE TABLE
lub ALTER TABLE
sprawozdania.
Tę wartość można ustawić w następujący sposób:
ALTER DATABASE CURRENT
SET ANSI_NULL_DEFAULT ON;
Jego wartość można pobrać w następujący sposób:
SELECT DATABASEPROPERTYEX('Music','IsAnsiNullDefault');
Wynik:
1
Możesz także użyć sys.databases
widok katalogu, aby zwrócić te ustawienia dla wszystkich baz danych.
SELECT
name,
is_ansi_nulls_on,
is_ansi_null_default_on
FROM sys.databases
ORDER BY name ASC;