A definição diz:
Quando SET ANSI_NULLS está ON, uma instrução SELECT que usa WHERE column_name = NULL retorna zero linhas, mesmo se houver valores nulos em column_name. Uma instrução SELECT que usa WHERE nome_da_coluna <> NULL retorna zero linhas, mesmo se houver valores não nulos em nome_da_coluna.
Isso significa que nenhum valor nulo será incluído nesta consulta?
SELECT Region
FROM employees
WHERE Region = @region
Ou diz ANSI_NULL
respeito apenas a consultas como esta (em que WHERE
inclui a palavra específica NULL
)?
SELECT Region
FROM employees
WHERE Region = NULL
sql
tsql
stored-procedures
Rodniko
fonte
fonte
Respostas:
Isso significa que nenhuma linha será retornada se
@region
forNULL
, quando usado em seu primeiro exemplo, mesmo se houver linhas na tabela ondeRegion
éNULL
.Quando
ANSI_NULLS
está ligado (que você deve sempre definir de qualquer maneira, uma vez que a opção de não tê-lo ativado será removida no futuro), qualquer operação de comparação onde (pelo menos) um dos operandos estáNULL
produz o terceiro valor lógico -UNKNOWN
( em oposição aTRUE
eFALSE
).UNKNOWN
os valores se propagam por meio de qualquer combinação de operadores booleanos se ainda não estiverem decididos (por exemplo,AND
com umFALSE
operando ouOR
com umTRUE
operando) ou negações (NOT
).A
WHERE
cláusula é usada para filtrar o conjunto de resultados produzido pelaFROM
cláusula, de modo que o valor geral daWHERE
cláusula deve serTRUE
para que a linha não seja filtrada. Portanto, se umUNKNOWN
for produzido por qualquer comparação, ele fará com que a linha seja filtrada.A resposta de @ user1227804 inclui esta citação:
de *
SET ANSI_NULLS
No entanto, não tenho certeza de que ponto ele está tentando fazer, pois se duas
NULL
colunas forem comparadas (por exemplo, em aJOIN
), a comparação ainda falhará: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
A consulta acima retorna 0 linhas, enquanto:
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)
Retorna uma linha. Portanto, mesmo quando ambos os operandos são colunas,
NULL
não é igualNULL
. E a documentação para=
não tem nada a dizer sobre os operandos:No entanto, 1 e 2 estão incorretos - o resultado de ambas as comparações é
UNKNOWN
.* O significado enigmático deste texto foi finalmente descoberto anos depois. O que realmente significa é que, para essas comparações, a configuração não tem efeito e sempre atua como se a configuração estivesse ativada . Teria sido mais claro se tivesse declarado que
SET ANSI_NULLS OFF
era a configuração que não teve efeito.fonte
Se
@Region
não for umnull
valor (digamos@Region = 'South'
), ele não retornará linhas onde o campo Região é nulo, independentemente do valor de ANSI_NULLS.ANSI_NULLS só fará diferença quando o valor de
@Region
énull
, ou seja, quando sua primeira consulta se tornar essencialmente a segunda.Nesse caso, ANSI_NULLS ON não retornará nenhuma linha (porque
null = null
produzirá um valor booleano desconhecido (também conhecido comonull
)) e ANSI_NULLS OFF retornará quaisquer linhas em que o campo Região seja nulo (porquenull = null
produzirátrue
)fonte
Se ANSI_NULLS for definido como "ON" e se aplicarmos =, <> no valor da coluna NULL ao escrever a instrução select, ele não retornará nenhum resultado.
Exemplo
create table #tempTable (sn int, ename varchar(50)) insert into #tempTable values (1, 'Manoj'), (2, 'Pankaj'), (3, NULL), (4, 'Lokesh'), (5, 'Gopal')
DEFINIR ANSI_NULLS LIGADO
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)
DEFINIR ANSI_NULLS DESLIGADO
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)
fonte
WHERE X IS NULL
eWHERE X = NULL
, e como ANSI_NULLS afeta o resultado. Apesar das tentativas excessivamente zelosas dos eleitores inferiores, ESTA deve ser a resposta aceita!DEFINIR ANSI_NULLS LIGADO
IT Retorna todos os valores, incluindo valores nulos na tabela
DEFINIR ANSI_NULLS desligado
Termina quando as colunas contêm valores nulos
fonte
Acho que o principal aqui é:
Nunca usuário:
@anything = NULL
@anything <> NULL
@anything != null
Sempre use:
@anything IS NULL
@anything IS NOT NULL
fonte
Definir ANSI NULLS OFF fará com que a comparação NULL = NULL retorne verdadeira. POR EXEMPLO :
SET ANSI_NULLS OFF select * from sys.tables where principal_id = Null
retornará algum resultado conforme mostrado abaixo: zcwInvoiceDeliveryType 744547 NULL zcExpenseRptStatusTrack 2099048 NULL ZCVendorPermissions 2840564 NULL ZCWOrgLevelClientFee 4322525 NULL
Embora esta consulta não retorne nenhum resultado:
SET ANSI_NULLS ON select * from sys.tables where principal_id = Null
fonte
https://docs.microsoft.com/en-us/sql/t-sql/statements/set-ansi-nulls-transact-sql
Quando SET ANSI_NULLS está ON, uma instrução SELECT que usa WHERE column_name = NULL retorna zero linhas, mesmo se houver valores nulos em column_name. Uma instrução SELECT que usa WHERE nome_da_coluna <> NULL retorna zero linhas, mesmo se houver valores não nulos em nome_da_coluna.
Por exemplo
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 !
fonte