Significado de 'SET' na mensagem de erro 'O valor nulo é eliminado por uma operação agregada ou outra operação SET'

18

Hoje, vi a mensagem 'aviso ANSI' acima ao executar o script de um colega (e não sei qual das muitas declarações fez com que o aviso fosse mostrado).

No passado, eu o ignorei: evito anular a mim mesmo e, portanto, qualquer coisa que os elimine é uma coisa boa no meu livro! No entanto, hoje a palavra 'SET' literalmente gritou comigo e percebi que não sabia qual o significado da palavra nesse contexto.

Meu primeiro pensamento, baseado no fato de estar em maiúscula, é que ele está se referindo à SETpalavra - chave e significa 'atribuição', como em

UPDATE <table> SET ...

...ON DELETE SET NULL...

SET IDENTITY_INSERT <table> ON

De acordo com a Ajuda do SQL Server, o recurso 'avisos ANSI' baseia-se na ISO / ANSI SQL-92, cuja especificação utiliza apenas o termo 'operação Set' em um título de subseção, portanto, em maiúsculas e minúsculas. seção de atribuição de dados. No entanto, depois de pesquisar rapidamente a mensagem de erro, vejo exemplos que são SELECTconsultas com aparentemente nenhuma atribuição envolvida.

Meu segundo pensamento, com base na redação do aviso do SQL Server, foi que o significado matemático de conjunto está implícito. No entanto, não acho que a agregação no SQL seja estritamente uma operação definida. Mesmo que a equipe do SQL Server considere uma operação definida, qual é o objetivo de colocar a palavra 'conjunto' em maiúsculas?

Ao pesquisar no Google, observei uma mensagem de erro do SQL Server:

Table 'T' does not have the identity property. Cannot perform SET operation.

As mesmas palavras 'operação SET' no mesmo caso aqui só podem se referir à atribuição da IDENTITY_INSERTpropriedade, o que me traz de volta ao meu primeiro pensamento.

Alguém pode lançar alguma luz sobre o assunto?

um dia quando
fonte
Eu sempre assumi que isso significava operação em um conjunto de linhas.
Martin Smith
@MartinSmith Eu não penso assim desde SETsempre em maiúsculas completos como uma palavra-chave
JNK
@JNK - Sim, pensando bem, suponho que deve haver alguma outra operação não agregada que gera esse aviso, então acho que se descobrirmos o que é isso pode explicar isso!
Martin Smith
SELECT * FROM sys.messages WHERE text LIKE '%SET operation%'fornece três outros resultados que parecem também indicar SETpalavras-chave.
Martin Smith
Pesquisei um pouco mais e pode estar se referindo a operações de conjunto como em conjuntos matemáticos. Eu encontrei um monte de referências na SS 2k docs para set operationsreferindo- UNIONe INTERSECTe EXCEPT, mas eu não posso obter o erro de chegar a NULLqualquer uma dessas circunstâncias. Eu acho que pode ser uma mensagem de erro herdada.
19412 JNK

Respostas:

13

Eu estava olhando a Especificação SQL-92 e vi uma passagem que me lembrou essa pergunta.

De fato, existe um aviso prescrito para esta situação, conforme indicado abaixo

b) Caso contrário, seja TX a tabela de coluna única resultante da aplicação <value expression>de cada linha de T e da eliminação de valores nulos. Se um ou mais valores nulos forem eliminados, uma condição de conclusão será gerada: aviso - valor nulo eliminado na função definida .

Suponho que SETna mensagem de erro do SQL Server seja uma referência à função definida dessa mensagem de erro, embora não tenha certeza de por que isso faria uma distinção entre agregadas e outras funções definidas, até onde posso ver que são sinônimos. O bit relevante da gramática está abaixo.

6.5  <set function specification>

         Function

         Specify a value derived by the application of a function to an
         argument.

         Format

         <set function specification> ::=
                COUNT <left paren> <asterisk> <right paren>
              | <general set function>

         <general set function> ::=
                <set function type>
                    <left paren> [ <set quantifier> ] <value expression> <right paren>


         <set function type> ::=
              AVG | MAX | MIN | SUM | COUNT

         <set quantifier> ::= DISTINCT | ALL
Martin Smith
fonte
9

Resposta rápida

O "outro SET * provavelmente está relacionado a versões mais antigas do SQL Server.

Eu costumava vê-lo mais quando trabalhava com o SQL Server 6.5 e 7, tenho certeza, mas já faz algum tempo. Muitas peculiaridades foram resolvidas + o SQL Server segue mais os padrões

Mais longo:

Atualmente, a mensagem é controlada pela SET ANSI_WARNINGSqual o padrão é ON.
Isso se refere apenas a se

  • um aviso é gerado por um valor NULL em um agregado.
  • o truncamento silencioso ocorre na inserção / atualização para campos do tipo varchar

Um exemplo:

DECLARE @foo TABLE (bar int NULL);
INSERT @foo VALUES (1), (2), (NULL);

SET ANSI_WARNINGS ON;
SELECT SUM(bar) FROM @foo;
SET ANSI_WARNINGS OFF;

SELECT SUM(bar) FROM @foo;

(3 row(s) affected)
---- -----------
ON   3
Warning: Null value is eliminated by an aggregate or other SET operation.
(1 row(s) affected)
---- -----------
OFF  3
(1 row(s) affected)

Outro exemplo:

DECLARE @foo TABLE (bar varchar(5) NULL);
SET ANSI_WARNINGS ON;
INSERT @foo VALUES ('123456'); -- error
GO
DECLARE @foo TABLE (bar varchar(5) NULL);
SET ANSI_WARNINGS OFF;
INSERT @foo VALUES ('123456'); -- OK
GO

Pessoalmente, ignoro o aviso e deixo SET ANSI_WARNINGS ON por causa das outras consequências para as colunas computadas e exibições indexadas de desativá-lo.

Por fim, pode haver um gatilho ou coluna computada ou exibição indexada gerando esse aviso em algum lugar

gbn
fonte
A redação da mensagem de erro definitivamente implica que existe (ou houve) alguma operação não agregada que também poderia eliminar NULLs para mim.
Martin Smith
@ Martin Smith: concordo. Poderia ser indireto, de acordo com minha (nova) última declaração. Ou alguma estratégia otimizadora que seria vista no plano
gbn 19/01
Pena que os documentos para algo mais antigo que o SQL Server 7.0 não pareçam estar online em nenhum lugar.
Martin Smith
11
exemplo (difícil de encontrar coisas tão antigas): kbalertz.com/Feedback.aspx?kbNumber=149921/EN-US
gbn
11
Embora, na verdade, pareça que a versão da mensagem do SQL Server 7.0 tenha sido apenas Aviso: Valor nulo eliminado do agregado. . O SET operationbit não foi adicionado até 2000.
Martin Smith
2

O outro lado do aviso refere-se às operações 'set' e não às operações 'SET' - que me parecem um erro de mensagem - por exemplo, também é produzido com funções de janelas:

select max(foo) over() as max_foo from (values (1), (2), (null)) as t(foo);
/*
max_foo
-------
2
2
2

Warning: Null value is eliminated by an aggregate or other SET operation.
*/
Jack Douglas
fonte
11
Parece que ele ainda está se referindo à parte agregação emboraMAX()
JNK
Isso é chamado de 'parte de agregação'? Eu sei o que você quer dizer, é claro, mas são operações diferentes - por exemplo, comparar select max(foo) from (values (1), (2), (null)) as t(foo) where 1=2;versusselect max(foo) over() from (values (1), (2), (null)) as t(foo) where 1=2;
Jack Douglas
2
É a função agregada :) Eu acredito que o erro está se referindo MAX(). Acho que o seu segundo exemplo tem mais a ver com a ordem das operações usando as funções da janela.
JNK
ok - o que quer dizer a partir dos docs SS
Jack Douglas