В определении говорится:
Когда для SET ANSI_NULLS установлено значение ON, инструкция SELECT, использующая WHERE column_name = NULL, возвращает нулевые строки, даже если в столбце имя_столбца есть нулевые значения. Оператор SELECT, использующий WHERE column_name <> NULL, возвращает нулевые строки, даже если в column_name есть ненулевые значения.
Означает ли это, что в этот запрос не будут включены нули?
SELECT Region
FROM employees
WHERE Region = @region
Или это ANSI_NULL
касается только таких запросов (где WHERE
есть конкретное слово NULL
)?
SELECT Region
FROM employees
WHERE Region = NULL
sql
tsql
stored-procedures
Роднико
источник
источник
Ответы:
Это означает , что ни одна строка не будет возвращена , если
@region
естьNULL
, при использовании в первом примере, даже если есть строки в таблице , гдеRegion
находитсяNULL
.Когда
ANSI_NULLS
он включен (который вы всегда должны устанавливать в любом случае, так как опция, чтобы не включать его, будет удалена в будущем), любая операция сравнения, в которой (по крайней мере) один из операндов,NULL
дает третье логическое значение -UNKNOWN
( в отличие отTRUE
иFALSE
).UNKNOWN
значения распространяются через любые комбинирующие логические операторы, если они еще не определены (например,AND
сFALSE
операндом илиOR
сTRUE
операндом) или отрицаниями (NOT
).Предложение
WHERE
используется для фильтрации набора результатов, созданногоFROM
предложением, так что общее значениеWHERE
предложения должно бытьTRUE
таким, чтобы строка не фильтровалась. Таким образом, если вUNKNOWN
результате какого-либо сравнения будет получено an, строка будет отфильтрована.@ user1227804 в ответ включает эту цитату:
от *
SET ANSI_NULLS
Однако я не уверен, какой смысл он пытается донести, поскольку при
NULL
сравнении двух столбцов (например, в aJOIN
) сравнение все равно не выполняется: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
Вышеупомянутый запрос возвращает 0 строк, тогда как:
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)
Возвращает одну строку. Таким образом, даже если оба операнда являются столбцами,
NULL
не равноNULL
. А в документации по=
операндам ничего не говорится:Однако и 1, и 2 неверны - результат обоих сравнений
UNKNOWN
.* Загадочный смысл этого текста был наконец открыт много лет спустя. На самом деле это означает, что для этих сравнений параметр не имеет никакого эффекта и всегда действует так, как если бы параметр был включен . Было бы яснее, если бы было указано, что
SET ANSI_NULLS OFF
это настройка, которая не имеет никакого влияния.источник
Если
@Region
не являетсяnull
значением (допустим@Region = 'South'
), он не будет возвращать строки, в которых поле «Регион» имеет значение NULL, независимо от значения ANSI_NULLS.ANSI_NULLS будет иметь значение только тогда, когда значение
@Region
равноnull
, то есть когда ваш первый запрос по существу становится вторым.В этом случае ANSI_NULLS ON не будет возвращать никаких строк (потому
null = null
что даст неизвестное логическое значение (akanull
)), а ANSI_NULLS OFF вернет любые строки, в которых поле Region имеет значение NULL (потому чтоnull = null
будет даватьtrue
)источник
Если для ANSI_NULLS установлено значение «ON», и если мы применим =, <> к значению столбца NULL при записи оператора select, то он не вернет никакого результата.
пример
create table #tempTable (sn int, ename varchar(50)) insert into #tempTable values (1, 'Manoj'), (2, 'Pankaj'), (3, NULL), (4, 'Lokesh'), (5, 'Gopal')
УСТАНОВИТЬ ANSI_NULLS ON
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)
ВЫКЛЮЧИТЬ 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)
источник
WHERE X IS NULL
иWHERE X = NULL
, и как ANSI_NULLS влияет на результат. Несмотря на излишне рьяные попытки оппонентов, ЭТО должен быть принятым ответом!УСТАНОВИТЬ ANSI_NULLS ON
IT возвращает все значения, включая нулевые значения в таблице
ВЫКЛЮЧИТЬ ANSI_NULLS
Заканчивается, когда столбцы содержат нулевые значения
источник
Думаю, здесь главное:
Никогда не пользователь:
@anything = NULL
@anything <> NULL
@anything != null
Всегда используйте:
@anything IS NULL
@anything IS NOT NULL
источник
Если установить ANSI NULLS OFF, сравнение NULL = NULL вернет истинное значение. Например:
SET ANSI_NULLS OFF select * from sys.tables where principal_id = Null
вернет результат, как показано ниже: zcwInvoiceDeliveryType 744547 NULL zcExpenseRptStatusTrack 2099048 NULL ZCVendorPermissions 2840564 NULL ZCWOrgLevelClientFee 4322525 NULL
Пока этот запрос не вернет никаких результатов:
SET ANSI_NULLS ON select * from sys.tables where principal_id = Null
источник
https://docs.microsoft.com/en-us/sql/t-sql/statements/set-ansi-nulls-transact-sql
Когда для SET ANSI_NULLS установлено значение ON, инструкция SELECT, использующая WHERE column_name = NULL, возвращает нулевые строки, даже если в столбце имя_столбца есть нулевые значения. Оператор SELECT, использующий WHERE column_name <> NULL, возвращает нулевые строки, даже если в column_name есть ненулевые значения.
Например,
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 !
источник