错误消息“空值已被聚合或其他 SET 操作消除”中“SET”的含义

one*_*hen 18 sql-server

我今天在运行同事的脚本时看到了上面的“ANSI警告”消息(我不知道许多语句中的哪一个导致显示警告)。

过去我忽略了它:我自己避免空值,所以任何可以消除它们的东西在我的书中都是一件好事!然而,今天“SET”这个词真的对我大喊大叫,我意识到我不知道这个词在这种情况下应该是什么意思。

我的第一个想法是,基于它是大写的事实,它指的是SET关键字,意思是“赋值”,如

UPDATE <table> SET ...

...ON DELETE SET NULL...

SET IDENTITY_INSERT <table> ON
Run Code Online (Sandbox Code Playgroud)

根据 SQL Server 帮助,“ANSI 警告”功能基于 ISO/ANSI SQL-92,该规范仅在小节标题中使用了术语“设置操作”,因此在标题大小写中,数据分配部分。但是,在快速搜索错误消息后,我看到了一些示例,这些示例是SELECT看似不涉及赋值的查询。

根据 SQL Server 警告的措辞,我的第二个想法是隐含了 set 的数学含义。但是,我不认为 SQL 中的聚合严格来说是一种集合操作。即使 SQL Server 团队认为它是一个集合操作,把“集合”这个词放在大写的目的是什么?

在谷歌搜索时,我注意到一条 SQL Server 错误消息:

Table 'T' does not have the identity property. Cannot perform SET operation.
Run Code Online (Sandbox Code Playgroud)

这里同样的情况下的“SET操作”这个词只能指IDENTITY_INSERT属性的赋值,这让我又回到了最初的想法。

任何人都可以对此事有所了解吗?

Mar*_*ith 14

我只是在浏览SQL-92 规范,看到一段让我想起了这个问题的段落。

事实上,对于这种情况有一个规定的警告,如下所示

b) 否则,令 TX 为单列表,它是将 应用于<value expression>T 的每一行并消除空值的结果。如果消除了一个或多个空值,则会引发完成条件:警告- set function 中消除了空值

我假设SETSQL Server 错误消息中的 是对该错误消息的 set 函数的引用,尽管我不确定为什么它会区分聚合和其他 set 函数,据我所知,它们是同义词。语法的相关部分如下。

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
Run Code Online (Sandbox Code Playgroud)


gbn*_*gbn 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;
Run Code Online (Sandbox Code Playgroud)

(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)
Run Code Online (Sandbox Code Playgroud)

另一个例子:

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
Run Code Online (Sandbox Code Playgroud)

就个人而言,我忽略了警告并将 SET ANSI_WARNINGS 保留为 ON,因为将其设置为 OFF 会对计算列和索引视图产生其他影响。

最后,可能有触发器或计算列或索引视图在某处生成此警告