it-swarm-eu.dev

Význam „SET“ v chybové zprávě „Nulová hodnota je eliminována agregovanou nebo jinou operací SET“

Při spuštění skriptu kolegy jsem dnes viděl výše uvedenou zprávu s upozorněním ANSI (a nevím, které z mnoha prohlášení způsobily, že se varování zobrazilo).

V minulosti jsem to ignoroval: sám se vyhýbám nullům, takže všechno, co by je eliminovalo, je v mé knize dobrá věc! Avšak dnes slovo „SET“ na mě doslova křičelo a uvědomil jsem si, že nevím, jaký význam má Slovo v této souvislosti.

Moje první myšlenka, na základě skutečnosti, že se jedná o velká písmena, je, že odkazuje na klíčové slovo SET a znamená „přiřazení“, jako v

UPDATE <table> SET ...

...ON DELETE SET NULL...

SET IDENTITY_INSERT <table> ON

Podle nápovědy k serveru SQL je funkce „ANSI varování“ založena na systému ISO/ANSI SQL-92, jehož specifikace umožňuje pouze jedno použití výrazu „Nastavit operaci“ v nadpisu podsekce, tedy v případě názvu sekce přiřazení dat. Po rychlém Googlingu chybové zprávy však vidím příklady, které jsou SELECT dotazy se zdánlivě bez přiřazení.

Moje druhá myšlenka, založená na formulaci varování serveru SQL, byla taková, že matematický význam množiny je implikován. Nemyslím si však, že agregace v SQL je přísně řečeno sadou operací. I když tým serveru SQL Server to považuje za operaci množiny, jaký je účel vložení slova „set“ velkými písmeny?

Během Googlingu jsem si všiml chybové zprávy serveru SQL:

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

Stejná slova „operace SET“ ve stejném případě zde mohou odkazovat pouze na přiřazení IDENTITY_INSERT vlastnost, která mě přivádí zpět k mé první myšlence.

Může někdo na tuto záležitost vrhnout nějaké světlo?

18
onedaywhen

Právě jsem se díval skrz specifikace SQL-92 a viděl jsem pasáž, která mi připomněla tuto otázku.

Ve skutečnosti existuje předepsané varování pro tuto situaci, jak je uvedeno níže

b) Jinak nechť TX je tabulka s jedním sloupcem, která je výsledkem použití <value expression> do každého řádku T a eliminace nulových hodnot. Pokud je eliminována jedna nebo více nulových hodnot, je vyvolána podmínka dokončení: varovné - nulová hodnota je eliminována v nastavené funkci .

Předpokládám, že SET v chybové zprávě SQL Server je odkazem na nastavenou funkci této chybové zprávy, i když nejsem si jistý, proč by rozlišoval mezi agregáty a dalšími nastavenými funkcemi, pokud vidí, že jsou synonymem. Relevantní bit gramatiky je níže.

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
13
Martin Smith

Rychlá odpověď

„Další SET * pravděpodobně souvisí se staršími verzemi SQL Serveru.

Kdysi jsem to viděl více, když jsem pracoval s SQL Server 6.5 a 7, jsem si jistý, ale je to už nějaký čas. Mnoho výstředností bylo vyžehleno + SQL Server se řídí standardy více

Delší:

Dnes je zpráva řízena SET ANSI_WARNINGS , které je standardně ON.
Týká se to čistě toho, zda

  • varování je generováno hodnotou NULL v agregátu.
  • při vložení/aktualizaci polí typu varchar dochází k tichému zkrácení

Jeden příklad:

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;

dává

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

Další příklad:

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

Osobně varování ignoruji a nechám SET ANSI_WARNINGS ON kvůli dalším důsledkům pro vypočítané sloupce a indexované pohledy na jeho vypnutí.

Nakonec by mohlo být někde spouštěcí nebo vypočítaný sloupec nebo indexované zobrazení, které toto varování generuje

9
gbn

Druhá strana varování se týká operací „set“, nikoli operací „SET“ - vypadá to jako chyba ve zprávě - například je také vytvořena pomocí funkcí okna:

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