Значення "SET" у повідомленні про помилку "Нульове значення усувається сукупною або іншою операцією SET"


18

Сьогодні я бачив вищезгадане повідомлення "ANSI попередження" під час запуску сценарію колеги (і не знаю, яка з багатьох заяв спричинила показ попередження).

У минулому я це ігнорував: я уникаю нулів і тому все, що могло б їх усунути, - це гарна річ у моїй книзі! Однак сьогодні слово "SET" буквально кричало на мене, і я зрозумів, що не знаю, яке значення цього слова має містити в цьому контексті.

Моя перша думка, заснована на тому, що це велика літера, полягає в тому, що вона посилається на SETключове слово і означає "призначення", як у

UPDATE <table> SET ...

...ON DELETE SET NULL...

SET IDENTITY_INSERT <table> ON

Відповідно до довідки SQL Server, функція "попередження про ANSI" базується на ISO / ANSI SQL-92, специфікація для якого використовує лише один термін "Встановити операцію" у заголовку підрозділу, отже, у випадку заголовка, у розділ призначення даних. Однак, після швидкого гуглінгу повідомлення про помилку я бачу приклади SELECTзапитів, які, здавалося б, не включають призначення.

Моя друга думка, заснована на формулюванні попередження SQL Server, полягала в тому, що математичне значення набору має на увазі. Однак я не думаю, що агрегація в SQL суворо говорить операцією набору. Навіть якщо команда SQL Server вважає це набір операцій, яка мета вводити слово "встановити" у великі літери?

Під час Googling я помітив повідомлення про помилку SQL Server:

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

Ті ж самі слова "SET SET" у тому самому випадку тут можуть стосуватися лише присвоєння IDENTITY_INSERTвластивості, що повертає мене до моєї першої думки.

Чи може хтось пролити якесь світло на цю справу?


Я завжди вважав, що це означає роботу над набором рядків.
Мартін Сміт

@MartinSmith Я не думаю, що так, оскільки SETзавжди в повному обсязі, як ключове слово
JNK

@JNK - Так, якщо подумати про це, я припускаю, що повинна бути якась інша сукупна операція, яка викликає це попередження, тому я думаю, якщо ми дізнаємося, що це може пояснити це!
Мартін Сміт

SELECT * FROM sys.messages WHERE text LIKE '%SET operation%'дає 3 інші результати, які, здається, також вказують на SETключові слова.
Мартін Сміт

Я ще трохи шукав, і це, можливо, стосується заданих операцій, як у математичних множинах. Я знайшов багато посилань у документах SS 2k на set operationsпосилання на UNIONта INTERSECTі EXCEPT, але я не можу отримати помилку, що з'явилася NULLв будь-якій з цих обставин. Я думаю, що це може бути повідомлення про помилку у спадщині
JNK

Відповіді:


13

Я просто переглядав специфікацію SQL-92 і побачив уривок, який нагадував мені це питання.

Насправді є прописане попередження про цю ситуацію, як зазначено нижче

b) В іншому випадку нехай TX - це стовпчаста таблиця, яка є результатом застосування <value expression>до кожного рядка T і усунення нульових значень. Якщо одне або кілька нульових значень усунене, тоді виконується умова завершення: попереджувальне - нульове значення усувається в заданій функції .

Я припускаю, що повідомлення SETу повідомленні про помилки SQL Server є посиланням на встановлену функцію цього повідомлення про помилку, хоча я не впевнений, чому це дозволило б розрізняти агрегати та інші задані функції, наскільки я бачу, що вони є синонімами. Відповідний біт граматики знаходиться нижче.

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

Швидка відповідь

"Інший SET *", ймовірно, пов'язаний зі старими версіями SQL Server.

Раніше я бачив це ще більше, коли працював із SQL Server 6.5 та 7, я впевнений, але минув певний час. Багато химерностей випрасовано + SQL Server більше відповідає стандартам

Довше:

У наш час повідомлення контролюється тим, за SET ANSI_WARNINGSякими типовими значеннями слід застосовувати ON.
Це стосується виключно того

  • попередження генерується значенням NULL у сукупності.
  • тихе усічення відбувається при вставці / оновленні для полів типу varchar

Один приклад:

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)

Інший приклад:

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

Особисто я ігнорую попередження і залишаю SET ANSI_WARNINGS ON через інші наслідки для обчислених стовпців та індексованих поглядів його вимкнення.

Нарешті, може бути тригер або обчислена колонка або індексований вигляд, де генерується десь попередження


Формулювання повідомлення про помилку, безумовно, означає, що існує (або була) якась сукупна операція, яка також могла б усунути NULL для мене.
Мартін Сміт

@Martin Smith: згоден. Це може бути непрямим, хоча згідно мого (нового) останнього твердження. Або якась стратегія оптимізації, яку можна було б побачити у плані
gbn

Ганьба, що документи для старих, ніж SQL Server 7.0, схоже, ніде не є в Інтернеті.
Мартін Сміт

1
Приклад (важко знайти речі цього старого): kbalertz.com/Feedback.aspx?kbNumber=149921/EN-US
gbn

1
Хоча насправді це виглядає так, ніби версія повідомлення SQL Server 7.0 була лише попередженням: нульове значення усунене з сукупності. . SET operationБіт не додано до 2000 року
Мартін Сміт

2

Інша сторона попередження стосується операцій "встановити", а не "SET" - це схоже на помилку для повідомлення - наприклад, воно також створюється за допомогою віконних функцій:

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
Здається, все ще йдеться про частину агрегаціїMAX()
JNK

Це називається "складовою частиною"? Я знаю, що ви, звичайно, маєте на увазі, але це різні операції - наприклад, порівняйте select max(foo) from (values (1), (2), (null)) as t(foo) where 1=2;протиselect max(foo) over() from (values (1), (2), (null)) as t(foo) where 1=2;
Джек Дуглас

2
Це сукупна функція :) Я вважаю, що помилка посилається MAX(). Я думаю, що ваш другий приклад має більше стосуватися порядку операцій із використанням віконних функцій.
JNK

добре - подивіться, що ви маєте на увазі під документами SS
Джек Дуглас
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.