В SQL Server, ANSI_NULLS
настройката ви позволява да укажете как NULL
стойностите се третират в заявки.
По-конкретно, ви позволява да зададете съвместимо с ISO поведение на Equals (=
) и не е равно на (<>
) оператори за сравнение, когато се използват с NULL
стойности.
ANSI_NULLS
може да бъде настроен на ON
или OFF
. A NULL
тест, който връща true с ANSI_NULLS OFF
всъщност може да върне false с ANSI_NULLS ON
.
Това може да бъде източник на много объркване и затова си струва да разберете точно как ANSI_NULLS
върши работа.
ANSI_NULLS
настройките могат да се задават на ниво база данни и на ниво сесия. Ако е ANSI_NULLS
настройката на ниво сесия не е посочена, SQL Server ще използва който и да е ANSI_NULLS
настройката се прилага към текущата база данни. Следователно можете да замените настройката на базата данни със собствена настройка на ниво сесия, когато пишете ad hoc заявки.
Важно нещо, което трябва да се отбележи е, че ODBC драйверът на SQL Server Native Client и OLE DB доставчикът на SQL Server Native Client за SQL Server автоматично задават ANSI_NULLS
до ON
при свързване. Тази настройка може да бъде конфигурирана в ODBC източници на данни, в атрибути на ODBC връзка или в OLE DB свойства на връзката, които са зададени в приложението, преди да се свърже с екземпляр на SQL Server.
Как да проверите ANSI_NULLS настройката на вашата сесия
Можете да използвате SESSIONPROPERTY()
функция за проверка на ANSI_NULLS
настройка за текущата сесия.
SELECT SESSIONPROPERTY('ANSI_NULLS');
Резултат:
+--------------------+ | (No column name) | |--------------------| | 1 | +--------------------+
В този случай, ANSI_NULLS
настройката за моята сесия е ON
.
Нула (0
) би означавало, че е изключено.
Как да промените ANSI_NULLS настройката на вашата сесия
Можете да зададете настройката ANSI_NULLS на вашата сесия на OFF
със следния код:
SET ANSI_NULLS OFF;
След това повторната проверка ще доведе до нула.
SELECT SESSIONPROPERTY('ANSI_NULLS');
Резултат:
+--------------------+ | (No column name) | |--------------------| | 0 | +--------------------+
Стойността по подразбиране за SET ANSI_NULLS
е OFF
. Въпреки това, както бе споменато по-горе, ODBC драйверът на SQL Server Native Client и OLE DB доставчикът на SQL Server Native Client за SQL Server автоматично задават ANSI_NULLS
до ON
при свързване.
Примери за това как ANSI_NULLS
Засяга заявки
Ето няколко основни примера за демонстриране на различните резултати, които можете да получите, в зависимост от стойността на ANSI_NULLS
настройка.
Те използват SET ANSI_NULLS
за да превключите ANSI_NULLS
настройка за текущата сесия.
ANSI_NULLS ON
SET ANSI_NULLS ON;
SELECT NULL
WHERE NULL = NULL;
Резултат:
(0 rows affected)
Когато ANSI_NULLS
е ON
, всички сравнения срещу NULL
стойността се оценява на UNKNOWN
.
В този случай не можем наистина да кажем, че NULL
равно на NULL
защото всяка стойност е неизвестна.
Следователно не се връщат редове за горната заявка.
ANSI_NULLS OFF
SET ANSI_NULLS OFF;
SELECT NULL
WHERE NULL = NULL;
Резултат:
+--------------------+ | (No column name) | |--------------------| | NULL | +--------------------+
Когато ANSI_NULLS
е OFF
, сравнения на всички данни с NULL
стойността се оценява на TRUE
ако стойността на данните е NULL
.
Същата логика се прилага при използване на оператора Not Equal To (<>
).
Нека разширим примера, за да включим оператора Not Equal To (<>
), както и сравнение между NULL
и не-NULL
стойност.
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;
Резултат:
(0 rows affected) (0 rows affected) (0 rows affected) (0 rows affected)
Както се очаква, не се връщат редове за нито една от заявките. Това е така, защото NULL
стойностите се третират като UNKNOWN
стойност, когато ANSI_NULLS
е 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;
Резултат:
+--------------------+ | (No column name) | |--------------------| | NULL | +--------------------+ (1 row affected) (0 rows affected) (0 rows affected) +--------------------+ | (No column name) | |--------------------| | Not NULL | +--------------------+ (1 row affected)
Получаваме различен резултат, когато ANSI_NULLS
е OFF
.
В този случай SQL Server не третира NULL
като UNKNOWN
. Той определя, че NULL
всъщност е равно на NULL
.
Това не е съвместимо със стандарта ANSI.
IS NULL
Предикат
За да работи скриптът по предназначение, независимо от ANSI_NULLS
опция за база данни или настройката на SET ANSI_NULLS
, използвайте IS NULL
и IS NOT NULL
в сравнения, които може да съдържат нулеви стойности
Ето какво се случва, когато пренапишем предишния пример, за да използваме IS NULL
и 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;
Резултат:
+--------------------+ | (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;
Резултат:
+--------------------+ | (No column name) | |--------------------| | NULL | +--------------------+ (1 row affected) (0 rows affected) (0 rows affected) +--------------------+ | (No column name) | |--------------------| | Not NULL | +--------------------+ (1 row affected)
Както се очакваше, получаваме същия резултат независимо от ANSI_NULLS
настройка.
Сравнителна таблица
Следващата таблица очертава вариантите, които можете да получите в зависимост от булевия израз и ANSI_NULLS
настройка.
Булев израз | ЗАДАДЕТЕ ANSI_NULLS ON | ИЗКЛЮЧИ ANSI_NULLS |
---|---|---|
NULL =NULL | НЕИЗВЕСТНО | ВЯРНО |
1 =NULL | НЕИЗВЕСТНО | НЕвярно |
NULL <> NULL | НЕИЗВЕСТНО | НЕвярно |
1 <> NULL | НЕИЗВЕСТНО | ВЯРНО |
NULL> NULL | НЕИЗВЕСТНО | НЕИЗВЕСТНО |
1> NULL | НЕИЗВЕСТНО | НЕИЗВЕСТНО |
NULL Е NULL | ВЯРНО | ВЯРНО |
1 Е NULL | НЕвярно | НЕвярно |
NULL НЕ Е NULL | НЕвярно | НЕвярно |
1 НЕ Е NULL | ВЯРНО | ВЯРНО |
Задаване на ANSI_NULLS на ниво база данни
Всяка база данни на SQL Server има ANSI_NULLS
настройка, която определя как се сравнява с NULL
стойностите се оценяват.
- Когато е зададено на
ON
, сравнения сNULL
стойността се оценява наUNKNOWN
. - Когато е зададено на
OFF
, сравнения на не-Unicode стойности сNULL
стойността се оценява наTRUE
ако и двете стойности саNULL
.
Можете да промените тази настройка в база данни със следния код:
ALTER DATABASE CURRENT
SET ANSI_NULLS ON;
Това задава ANSI_NULLS
до ON
за текущата база данни. Можете да размените CURRENT
с името на база данни, ако предпочитате.
Можете да проверите текущата настройка с DATABASEPROPERTYEX()
функция.
SELECT DATABASEPROPERTYEX('Music','IsAnsiNullsEnabled');
Резултат:
1
Както споменахме, можете да замените тази настройка, когато пишете ad hoc заявки, като я зададете на ниво сесия, както направихме по-рано.
Докато сме по темата, трябва да спомена, че базите данни на SQL Server също имат ANSI_NULL_DEFAULT
настройка. Тази настройка определя стойността по подразбиране, NULL
или NOT NULL
, от колона или CLR дефиниран от потребителя тип, за който възможността за нулиране не е изрично дефинирана в CREATE TABLE
или ALTER TABLE
изявления.
Тази стойност може да бъде зададена по следния начин:
ALTER DATABASE CURRENT
SET ANSI_NULL_DEFAULT ON;
Стойността му може да бъде извлечена по следния начин:
SELECT DATABASEPROPERTYEX('Music','IsAnsiNullDefault');
Резултат:
1
Можете също да използвате sys.databases
изглед на каталог, за да върнете тези настройки за всички бази данни.
SELECT
name,
is_ansi_nulls_on,
is_ansi_null_default_on
FROM sys.databases
ORDER BY name ASC;