Significato di "SET" nel messaggio di errore "Il valore null viene eliminato da un'operazione SET aggregata o altra"


18

Ho visto il messaggio "ANSI warning" sopra riportato oggi mentre eseguivo lo script di un collega (e non so quale delle tante affermazioni abbia causato la visualizzazione dell'avviso).

In passato l'ho ignorato: evito me stesso i null e quindi tutto ciò che li eliminerebbe è una buona cosa nel mio libro! Tuttavia, oggi la parola "SET" mi ha letteralmente urlato addosso e mi sono reso conto che non so quale sia il significato della parola in questo contesto.

Il mio primo pensiero, basato sul fatto che è in maiuscolo, è che si riferisce alla SETparola chiave e significa "assegnazione", come in

UPDATE <table> SET ...

...ON DELETE SET NULL...

SET IDENTITY_INSERT <table> ON

Secondo la Guida di SQL Server, la funzione "Avvertenze ANSI" si basa su ISO / ANSI SQL-92, la specifica per la quale fa un solo uso del termine "Imposta operazione" in un titolo di sottosezione, quindi nel caso del titolo, nella sezione di assegnazione dei dati. Tuttavia, dopo una rapida ricerca su Google del messaggio di errore, vedo esempi che sono SELECTquery senza apparentemente implicazioni.

Il mio secondo pensiero, basato sulla formulazione dell'avvertimento di SQL Server, era che il significato matematico di set è implicito. Tuttavia, non penso che l'aggregazione in SQL stia parlando strettamente un'operazione impostata. Anche se il team di SQL Server lo considera un'operazione set, qual è lo scopo di mettere la parola "set" in maiuscolo?

Durante la ricerca su Google ho notato un messaggio di errore di SQL Server:

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

Le stesse parole "operazione SET" nello stesso caso qui possono riferirsi solo all'assegnazione della IDENTITY_INSERTproprietà, il che mi riporta al mio primo pensiero.

Qualcuno può far luce sulla questione?


Ho sempre pensato che significasse operazione su una serie di file.
Martin Smith,

@MartinSmith Non credo che SETsia sempre pieno di maiuscole come una parola chiave
JNK

@JNK - Sì, a pensarci suppongo che ci debba essere qualche altra operazione non aggregata che solleva quell'avvertimento, quindi immagino che se scopriamo di cosa si tratta potrebbe spiegarlo!
Martin Smith,

SELECT * FROM sys.messages WHERE text LIKE '%SET operation%'fornisce altri 3 risultati che sembrano indicare anche SETparole chiave.
Martin Smith,

Ho fatto qualche ricerca in più e potrebbe effettivamente riferirsi a operazioni di set come in set di matematica. Ho trovato molti riferimenti nei documenti di SS 2k a cui fare set operationsriferimento UNIONe INTERSECTe EXCEPT, ma non riesco a trovare l'errore NULLin nessuna di queste circostanze. Penso che potrebbe essere un messaggio di errore legacy.
JNK,

Risposte:


13

Stavo solo esaminando la specifica SQL-92 e ho visto un passaggio che mi ha ricordato questa domanda.

Esiste infatti un avvertimento prescritto per questa situazione come indicato di seguito

b) Altrimenti, lascia che TX sia la tabella a colonna singola che è il risultato dell'applicazione <value expression>di ogni riga di T e dell'eliminazione di valori null. Se uno o più valori null vengono eliminati, viene sollevata una condizione di completamento: avviso- valore null eliminato nella funzione set .

Suppongo che SETnel messaggio di errore di SQL Server sia un riferimento alla funzione set di quel messaggio di errore, anche se non sono sicuro del motivo per cui farebbe una distinzione tra aggregati e altre funzioni set, per quanto posso vedere sono sinonimi. Il bit rilevante della grammatica è di seguito.

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

Risposta rapida

L '"altro SET * è probabilmente correlato alle versioni precedenti di SQL Server.

Lo vedevo di più quando lavoravo con SQL Server 6.5 e 7 ne sono sicuro, ma è passato del tempo. Molte stranezze sono state risolte + SQL Server segue più gli standard

Più a lungo:

Al giorno d'oggi, il messaggio è controllato da SET ANSI_WARNINGSquale impostazione predefinita è ON.
Ciò si riferisce esclusivamente al se

  • un avviso viene generato da un valore NULL in un aggregato.
  • il troncamento silenzioso si verifica sull'inserimento / aggiornamento dei campi di tipo varchar

Un esempio:

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)

Un altro esempio:

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 l'avvertimento e lascio SET ANSI_WARNINGS ON a causa delle altre conseguenze sulle colonne calcolate e sulle viste indicizzate impostandolo su OFF.

Infine, potrebbe esserci un trigger o una colonna calcolata o una vista indicizzata che genera questo avviso da qualche parte


La formulazione del messaggio di errore implica sicuramente che esiste (o è stata) un'operazione non aggregata che potrebbe anche eliminare i NULL per me.
Martin Smith,

@Martin Smith: d'accordo. Potrebbe essere indiretto secondo la mia (nuova) ultima affermazione. O qualche strategia di ottimizzazione che verrebbe vista nel piano
gbn

Peccato che i documenti per qualcosa di più vecchio di SQL Server 7.0 non sembrano essere online da nessuna parte.
Martin Smith,

1
esempio (è difficile trovare roba così vecchia): kbalertz.com/Feedback.aspx?kbNumber=149921/EN-US
gbn

1
Anche se in realtà sembra che la versione di SQL Server 7.0 del messaggio fosse solo Avviso: valore null eliminato dall'aggregato. . Il SET operationpezzo non è stato aggiunto fino al 2000.
Martin Smith,

2

L'altro lato dell'avvertimento si riferisce alle operazioni 'set' e non alle operazioni 'SET' - che mi sembra un bug di messaggio - ad esempio, è anche prodotto con funzioni di windowing:

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
Sembra che si riferisca comunque alla parte di aggregazioneMAX()
JNK

Si chiama "parte di aggregazione"? So cosa intendi ovviamente, ma sono diverse operazioni - ad es. Confronto select max(foo) from (values (1), (2), (null)) as t(foo) where 1=2;controselect max(foo) over() from (values (1), (2), (null)) as t(foo) where 1=2;
Jack Douglas

2
È la funzione aggregata :) Credo che l'errore si riferisca a MAX(). Penso che il tuo secondo esempio debba fare di più con l'ordine delle operazioni usando le funzioni della finestra.
JNK,

ok - capisci cosa intendi dai documenti delle SS
Jack Douglas,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.