Znaczenie „SET” w komunikacie o błędzie „Wartość zerowa jest eliminowana przez agregację lub inną operację SET”

18

Podczas uruchamiania skryptu współpracownika widziałem powyższy komunikat „Ostrzeżenie ANSI” (i nie wiem, które z wielu stwierdzeń spowodowało wyświetlenie ostrzeżenia).

W przeszłości ignorowałem to: sam unikam zer, więc wszystko, co je wyeliminowałoby, jest dobrą rzeczą w mojej książce! Jednak dzisiaj słowo „SET” dosłownie krzyknęło na mnie i zdałem sobie sprawę, że nie wiem, jakie znaczenie powinno mieć w tym kontekście.

Moją pierwszą myślą, opartą na tym, że jest wielka, jest to, że odnosi się do SETsłowa kluczowego i oznacza „przypisanie”, jak w

UPDATE <table> SET ...

...ON DELETE SET NULL...

SET IDENTITY_INSERT <table> ON

Zgodnie z Pomocą programu SQL Server funkcja „ostrzeżeń ANSI” jest oparta na normie ISO / ANSI SQL-92, dla której specyfikacja używa tylko jednego terminu „Ustaw operację” w tytule podsekcji, stąd w przypadku tytułu w sekcja przypisywania danych. Jednak po szybkim przejrzeniu komunikatu o błędzie widzę przykłady, które są SELECTzapytaniami, które najwyraźniej nie wiążą się z przypisaniem.

Moja druga myśl, oparta na sformułowaniu ostrzeżenia SQL Server, była taka, że ​​implikowane jest matematyczne znaczenie zestawu. Jednak nie sądzę, że agregacja w SQL jest ściśle operacją ustawioną. Nawet jeśli zespół SQL Server uważa, że ​​jest to operacja ustawiania, jaki jest cel umieszczania słowa „set” wielkimi literami?

Podczas przeglądania Google zauważyłem komunikat o błędzie programu SQL Server:

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

Te same słowa „operacja SET” w tym samym przypadku mogą odnosić się tylko do przypisania IDENTITY_INSERTwłaściwości, co sprowadza mnie z powrotem do mojej pierwszej myśli.

Czy ktoś może rzucić jakieś światło na tę sprawę?

oneedaywhen
źródło
Zawsze zakładałem, że oznacza to operację na zestawie rzędów.
Martin Smith
@MartinSmith Nie sądzę, ponieważ SETjest zawsze pisane dużymi literami jak słowo kluczowe
JNK,
@JNK - Tak, myśląc o tym, zakładam, że musi istnieć jakaś inna nieskumulowana operacja, która podnosi to ostrzeżenie, więc myślę, że jeśli dowiemy się, co to może to wyjaśnić!
Martin Smith
SELECT * FROM sys.messages WHERE text LIKE '%SET operation%'daje 3 inne wyniki, które wydają się wskazywać również na SETsłowo kluczowe.
Martin Smith
Zrobiłem trochę więcej poszukiwań i może to w rzeczywistości dotyczyć operacji na zestawach, jak w zestawach matematycznych. Znalazłem wiele odniesień w SS 2k Dokumentów set operationsodnosząc się do UNIONi INTERSECTa EXCEPT, ale nie mogę dostać błąd wymyślić NULLw żadnej z tych okoliczności. Myślę, że może to być starszy komunikat o błędzie.
JNK

Odpowiedzi:

13

Właśnie przeglądałem specyfikację SQL-92 i zobaczyłem fragment, który przypomniał mi to pytanie.

W rzeczywistości istnieje określone ostrzeżenie dla tej sytuacji, jak wskazano poniżej

b) W przeciwnym razie niech TX będzie tabelą jednokolumnową, która jest wynikiem zastosowania <value expression>do każdego wiersza T i wyeliminowania wartości zerowych. Jeśli jedna lub więcej wartości zerowych zostanie wyeliminowanych, wówczas zostanie spełniony warunek ukończenia: ostrzeżenie - wartość zerowa wyeliminowana w funkcji set .

Zakładam, że SETw komunikacie o błędzie programu SQL Server jest odniesieniem do funkcji zestawu tego komunikatu o błędzie, chociaż nie jestem pewien, dlaczego wprowadziłoby rozróżnienie między agregacjami a innymi funkcjami zestawu, o ile widzę, że są one synonimami. Odpowiednia część gramatyki znajduje się poniżej.

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
źródło
9

Szybka odpowiedź

„Inny zestaw * jest prawdopodobnie związany ze starszymi wersjami programu SQL Server.

Kiedyś pracowałem z SQL Server 6.5 i 7, widziałem to jeszcze bardziej, ale minęło trochę czasu. Wiele dziwactw zostało rozwiązanych + SQL Server bardziej odpowiada standardom

Dłużej:

Obecnie wiadomość jest kontrolowana przez SET ANSI_WARNINGSdomyślną wartość ON.
Odnosi się to wyłącznie do tego, czy

  • ostrzeżenie jest generowane przez wartość NULL w agregacie.
  • w przypadku pól typu varchar występuje ciche wycinanie

Jeden przykład:

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;

daje

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

Inny przykład:

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

Osobiście ignoruję ostrzeżenie i pozostawiam SET ANSI_WARNINGS ON z powodu innych konsekwencji dla kolumn obliczeniowych i indeksowanych widoków ustawienia OFF.

Wreszcie może istnieć wyzwalacz lub kolumna obliczeniowa lub indeksowany widok generujący gdzieś to ostrzeżenie

gbn
źródło
Sformułowanie komunikatu o błędzie zdecydowanie sugeruje, że istnieje (lub była) jakaś operacja nie agregująca, która mogłaby również wyeliminować dla mnie wartości NULL.
Martin Smith
@Martin Smith: zgadzam się. Może to być jednak pośrednie, zgodnie z moim (nowym) ostatnim stwierdzeniem. Albo jakiś strategia optymalizator, które byłyby widoczne w planie
gbn
Szkoda, że ​​dokumenty starsze niż SQL Server 7.0 nie wydają się być nigdzie online.
Martin Smith,
1
przykład (trudno znaleźć takie stare): kbalertz.com/Feedback.aspx?kbNumber=149921/EN-US
gbn
1
Chociaż w rzeczywistości wygląda na to, że wersja komunikatu programu SQL Server 7.0 była tylko ostrzeżeniem: wartość zerowa została wyeliminowana z agregacji. . SET operationBit nie został dodany do 2000 roku
Martin Smith
2

Druga strona ostrzeżenia odnosi się do operacji „set”, a nie do operacji „SET” - co dla mnie wygląda na komunikat o błędzie - na przykład jest on również wytwarzany z funkcjami okienkowania:

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
źródło
1
Wygląda jednak na to, że wciąż odnosi się do części agregacyjnejMAX()
JNK,
Czy to się nazywa „część agregacyjna”? Wiem, co masz na myśli, oczywiście, ale są to różne operacje - np. Porównanie select max(foo) from (values (1), (2), (null)) as t(foo) where 1=2;zselect max(foo) over() from (values (1), (2), (null)) as t(foo) where 1=2;
Jack Douglas
2
To funkcja agregująca :) Myślę, że błąd dotyczy MAX(). Myślę, że twój drugi przykład ma więcej do czynienia z kolejnością operacji przy użyciu funkcji okna.
JNK
ok - zobacz, co masz na myśli z dokumentów SS
Jack Douglas,