Significado de 'SET' en el mensaje de error 'El valor nulo es eliminado por un agregado u otra operación SET'


18

Vi el mensaje anterior de 'advertencia ANSI' hoy cuando ejecuté el script de un colega (y no sé cuál de las muchas declaraciones causó que se mostrara la advertencia).

En el pasado lo ignoré: evito los valores nulos y, por lo tanto, ¡cualquier cosa que los elimine es algo bueno en mi libro! Sin embargo, hoy la palabra 'SET' literalmente me gritó y me di cuenta de que no sé cuál es el significado de la palabra en este contexto.

Mi primer pensamiento, basado en el hecho de que es mayúscula, es que se refiere a la SETpalabra clave y significa 'asignación', como en

UPDATE <table> SET ...

...ON DELETE SET NULL...

SET IDENTITY_INSERT <table> ON

De acuerdo con la Ayuda de SQL Server, la función 'Advertencias ANSI' se basa en ISO / ANSI SQL-92, la especificación para la cual hace un solo uso del término 'Establecer operación' en un título de subsección, por lo tanto, en el caso del título, en el sección de asignación de datos. Sin embargo, después de buscar rápidamente en Google el mensaje de error, veo ejemplos que son SELECTconsultas en las que aparentemente no hay ninguna tarea involucrada.

Mi segundo pensamiento, basado en la redacción de la advertencia de SQL Server, fue que el significado matemático de conjunto está implícito. Sin embargo, no creo que la agregación en SQL sea estrictamente una operación establecida. Incluso si el equipo de SQL Server lo considera una operación de conjunto, ¿cuál es el propósito de poner la palabra 'conjunto' en mayúsculas?

Mientras buscaba en Google, noté un mensaje de error de SQL Server:

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

Las mismas palabras 'operación SET' en el mismo caso aquí solo pueden referirse a la asignación de la IDENTITY_INSERTpropiedad, lo que me lleva a mi primer pensamiento.

¿Alguien puede arrojar alguna luz sobre el asunto?


Siempre supuse que significaba operar en un conjunto de filas.
Martin Smith

@ MartininSmith No lo creo, ya SETque siempre está en mayúsculas como una palabra clave
JNK

@JNK - Sí, al pensarlo, supongo que debe haber alguna otra operación no agregada que genere esa advertencia, ¡así que supongo que si descubrimos qué es eso, podría explicarlo!
Martin Smith

SELECT * FROM sys.messages WHERE text LIKE '%SET operation%'da otros 3 resultados que parecen indicar SETpalabras clave también.
Martin Smith

Hice un poco más de búsqueda y en realidad puede referirse a operaciones de conjuntos como en conjuntos matemáticos. He encontrado una gran cantidad de referencias en SS 2k Docs para set operationsreferirse a UNIONe INTERSECTy EXCEPT, pero no puedo obtener el error para llegar a NULLcualquiera de esas circunstancias. Creo que puede ser un mensaje de error heredado.
JNK

Respuestas:


13

Estaba mirando la especificación SQL-92 y vi un pasaje que me recordó esta pregunta.

De hecho, hay una advertencia prescrita para esta situación como se indica a continuación

b) De lo contrario, deje que TX sea la tabla de una sola columna que es el resultado de aplicar el <value expression>a cada fila de T y eliminar los valores nulos. Si se eliminan uno o más valores nulos, se genera una condición de finalización: advertencia : se elimina el valor nulo en la función establecida .

Supongo que el SETmensaje de error en el servidor SQL es una referencia a la función de conjunto de ese mensaje de error, aunque no estoy seguro de por qué haría una distinción entre agregados y otras funciones de conjunto, por lo que puedo ver, son sinónimos. El bit relevante de la gramática está abajo.

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

9

Respuesta rápida

El "otro SET * probablemente esté relacionado con versiones anteriores de SQL Server.

Solía ​​verlo más cuando trabajaba con SQL Server 6.5 y 7, estoy seguro, pero ha pasado algún tiempo. Se han solucionado muchas peculiaridades + SQL Server sigue los estándares más

Más:

Hoy en día, el mensaje está controlado por los SET ANSI_WARNINGSvalores predeterminados ON.
Esto se relaciona únicamente con si

  • Se genera una advertencia mediante un valor NULL en un agregado.
  • se produce un truncamiento silencioso al insertar / actualizar los campos de tipo varchar

Un ejemplo:

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;

da

(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)

Otro ejemplo:

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

Personalmente, ignoro la advertencia y dejo SET ANSI_WARNINGS ON debido a las otras consecuencias para las columnas calculadas y las vistas indizadas de desactivarlo.

Finalmente, podría haber un disparador o una columna calculada o una vista indizada que genere esta advertencia en alguna parte


La redacción del mensaje de error definitivamente implica que hay (o hubo) alguna operación no agregada que también podría eliminar NULL para mí.
Martin Smith

@ Martin Smith: de acuerdo. Sin embargo, podría ser indirecta según mi (nueva) última declaración. O alguna estrategia optimizadora que se vería en el plan
gbn

Es una pena que los documentos para cualquier cosa anterior a SQL Server 7.0 no parecen estar en línea en ningún lugar.
Martin Smith

1
ejemplo (difícil de encontrar cosas así de antiguas): kbalertz.com/Feedback.aspx?kbNumber=149921/EN-US
gbn

1
Aunque en realidad parece que la versión de SQL Server 7.0 del mensaje era solo Advertencia: el valor nulo se eliminó del agregado. . El SET operationbit no se agregó hasta el año 2000.
Martin Smith

2

El otro lado de la advertencia se refiere a las operaciones 'establecer', no a las operaciones 'SET', que me parecen un mensaje de error, por ejemplo, también se produce con funciones de ventanas:

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.
*/

1
Parece que todavía se refiere a la parte de agregación sin embargoMAX()
JNK

¿Se llama eso la 'parte de agregación'? Sé lo que quieres decir, por supuesto, pero son operaciones diferentes, por ejemplo, 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 el

2
Es la función agregada :) Creo que el error se refiere MAX(). Creo que su segundo ejemplo tiene que ver más con el orden de las operaciones utilizando funciones de ventana.
JNK

ok - mira lo que quieres decir con los documentos de las SS
Jack Douglas
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.