Sqlserver
 sql >> Base de Dados >  >> RDS >> Sqlserver

SQL Server ANSI_NULLS explicado


No SQL Server, o ANSI_NULLS configuração permite que você especifique como NULL os valores são tratados nas consultas.

Mais especificamente, ele permite que você especifique o comportamento compatível com ISO do Equals (= ) e Diferente de (<> ) operadores de comparação quando são usados ​​com NULL valores.

ANSI_NULLS pode ser definido como ON ou OFF . Um NULL teste que retorna true com ANSI_NULLS OFF pode realmente retornar false com ANSI_NULLS ON .

Isso pode causar muita confusão, então vale a pena entender exatamente como ANSI_NULLS funciona.

ANSI_NULLS as configurações podem ser definidas no nível do banco de dados e no nível da sessão. Se um ANSI_NULLS configuração no nível da sessão não for especificada, o SQL Server usará qualquer ANSI_NULLS configuração é aplicada ao banco de dados atual. Portanto, você pode substituir a configuração do banco de dados por sua própria configuração de nível de sessão ao escrever consultas ad hoc.

Uma coisa importante a ser observada é que o driver ODBC do SQL Server Native Client e o Provedor OLE DB do SQL Server Native Client para SQL Server definem automaticamente ANSI_NULLS para ON ao conectar. Essa configuração pode ser definida em fontes de dados ODBC, em atributos de conexão ODBC ou em propriedades de conexão OLE DB que são definidas no aplicativo antes de se conectar a uma instância do SQL Server.

Como verificar a configuração ANSI_NULLS da sua sessão


Você pode usar o SESSIONPROPERTY() função para verificar o ANSI_NULLS configuração para a sessão atual.
SELECT SESSIONPROPERTY('ANSI_NULLS');

Resultado:
+--------------------+
| (No column name)   |
|--------------------|
| 1                  |
+--------------------+

Neste caso, o ANSI_NULLS configuração para minha sessão é ON .

Um zero (0 ) significaria que está desligado.

Como alterar a configuração ANSI_NULLS da sua sessão


Você pode definir a configuração ANSI_NULLS da sua sessão para OFF com o seguinte código:
SET ANSI_NULLS OFF;

Em seguida, verificar novamente produzirá um zero.
SELECT SESSIONPROPERTY('ANSI_NULLS');

Resultado:
+--------------------+
| (No column name)   |
|--------------------|
| 0                  |
+--------------------+

O valor padrão para SET ANSI_NULLS está OFF . No entanto, conforme mencionado acima, o driver ODBC do SQL Server Native Client e o Provedor OLE DB do SQL Server Native Client para SQL Server definem automaticamente ANSI_NULLS para ON ao conectar.

Exemplos de como ANSI_NULLS Afeta as consultas


Aqui estão alguns exemplos básicos para demonstrar os diferentes resultados que você pode obter, dependendo do valor do ANSI_NULLS contexto.

Estes usam SET ANSI_NULLS para alternar o ANSI_NULLS configuração para a sessão atual.

ANSI_NULLS ON

SET ANSI_NULLS ON;

SELECT NULL
WHERE NULL = NULL;

Resultado:
(0 rows affected)

Quando ANSI_NULLS está ON , todas as comparações com um NULL valor avaliado como UNKNOWN .

Neste caso, não podemos dizer que NULL igual a NULL porque cada valor é desconhecido.

Portanto, nenhuma linha é retornada para a consulta acima.

ANSI_NULLS OFF

SET ANSI_NULLS OFF;

SELECT NULL
WHERE NULL = NULL;

Resultado:
+--------------------+
| (No column name)   |
|--------------------|
| NULL               |
+--------------------+

Quando ANSI_NULLS está OFF , comparações de todos os dados com um NULL valor avaliado como TRUE se o valor dos dados for NULL .

A mesma lógica se aplica ao usar o operador Diferente de (<> ).

Vamos expandir o exemplo para incluir o operador Diferente de (<> ), bem como uma comparação entre NULL e um não-NULL valor.

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;

Resultado:
(0 rows affected)
(0 rows affected)
(0 rows affected)
(0 rows affected)

Conforme esperado, nenhuma linha é retornada para nenhuma das consultas. Isso ocorre porque NULL os valores são tratados como um UNKNOWN valor quando ANSI_NULLS está 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;

Resultado:
+--------------------+
| (No column name)   |
|--------------------|
| NULL               |
+--------------------+
(1 row affected)
(0 rows affected)
(0 rows affected)
+--------------------+
| (No column name)   |
|--------------------|
| Not NULL           |
+--------------------+
(1 row affected)

Obtemos um resultado diferente quando ANSI_NULLS está OFF .

Nesse caso, o SQL Server não trata NULL como UNKNOWN . Ele determina que NULL é de fato igual a NULL .

Isso não é compatível com o padrão ANSI.

O IS NULL Predicado


Para que um script funcione como pretendido, independentemente do ANSI_NULLS opção de banco de dados ou a configuração de SET ANSI_NULLS , use IS NULL e IS NOT NULL em comparações que podem conter valores nulos

Veja o que acontece quando reescrevemos o exemplo anterior para usar IS NULL e 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;

Resultado:
+--------------------+
| (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;

Resultado:
+--------------------+
| (No column name)   |
|--------------------|
| NULL               |
+--------------------+
(1 row affected)
(0 rows affected)
(0 rows affected)
+--------------------+
| (No column name)   |
|--------------------|
| Not NULL           |
+--------------------+
(1 row affected)

Como esperado, obtemos o mesmo resultado independentemente do ANSI_NULLS contexto.

Tabela de comparação


A tabela a seguir descreve as variações que você pode obter dependendo da expressão booleana e ANSI_NULLS contexto.
Expressão booleana ATIVAR ANSI_NULLS DEFINIR ANSI_NULLS OFF
NULO =NULO DESCONHECIDO VERDADEIRO
1 =NULO DESCONHECIDO FALSO
NULO <> NULO DESCONHECIDO FALSO
1 <> NULO DESCONHECIDO VERDADEIRO
NULO> NULO DESCONHECIDO DESCONHECIDO
1> NULO DESCONHECIDO DESCONHECIDO
NULO É NULO VERDADEIRO VERDADEIRO
1 É NULO FALSO FALSO
NULO NÃO É NULO FALSO FALSO
1 NÃO É NULO VERDADEIRO VERDADEIRO

Definindo ANSI_NULLS no nível do banco de dados


Cada banco de dados SQL Server tem um ANSI_NULLS configuração, que determina como as comparações com NULL valores são avaliados.
  • Quando definido como ON , comparações com um NULL valor avaliado como UNKNOWN .
  • Quando definido como OFF , comparações de valores não Unicode com um NULL valor avaliado como TRUE se ambos os valores forem NULL .

Você pode alterar essa configuração em um banco de dados com o seguinte código:
ALTER DATABASE CURRENT
SET ANSI_NULLS ON;

Isso define ANSI_NULLS para ON para o banco de dados atual. Você pode trocar CURRENT com o nome de um banco de dados, se preferir.

Você pode verificar a configuração atual com o DATABASEPROPERTYEX() função.
SELECT DATABASEPROPERTYEX('Music','IsAnsiNullsEnabled');

Resultado:
1

Conforme mencionado, você pode substituir essa configuração ao escrever consultas ad hoc, definindo-a no nível da sessão, como fizemos anteriormente.

Enquanto estamos no tópico, devo mencionar que os bancos de dados SQL Server também têm um ANSI_NULL_DEFAULT contexto. Esta configuração determina o valor padrão, NULL ou NOT NULL , de uma coluna ou tipo CLR definido pelo usuário para o qual a nulidade não é explicitamente definida em CREATE TABLE ou ALTER TABLE declarações.

Este valor pode ser definido assim:
ALTER DATABASE CURRENT
SET ANSI_NULL_DEFAULT ON;

Seu valor pode ser recuperado assim:
SELECT DATABASEPROPERTYEX('Music','IsAnsiNullDefault');

Resultado:
1

Você também pode usar o sys.databases exibição de catálogo para retornar essas configurações para todos os bancos de dados.
SELECT
    name,
    is_ansi_nulls_on,
    is_ansi_null_default_on
FROM sys.databases
ORDER BY name ASC;