【发布时间】:2019-05-22 05:19:22
【问题描述】:
我已经阅读了在当前会话中使用“SET ANSI_NULLS OFF”以便能够将 NULL = NULL 评估为真,例如以下示例显示了 ANSI_NULLS ON 和 ANSI_NULLS OFF 之间的区别:
查询 A:
SET ANSI_NULLS OFF
IF(NULL = NULL)
SELECT 'NULL = NULL'
ELSE
SELECT 'NO MATCH'
结果:'NULL = NULL'
查询 B:
SET ANSI_NULLS ON
IF(NULL = NULL)
SELECT 'NULL = NULL'
ELSE
SELECT 'NO MATCH'
结果:'不匹配'
所以这显示了 ON 和 OFF 设置之间的区别。
当在标准选择语句的 where 子句中使用它时,这似乎也有效。
但是,当源字段和目标字段为空时,这似乎在合并中不起作用。
重现一个简单的场景:
创建测试表:
CREATE TABLE [dbo].[TestTable]
(
[Id] [INT] IDENTITY(1,1) NOT NULL,
[SomeText] [NVARCHAR](100) NULL,
[Counter] [INT] NOT NULL,
CONSTRAINT [PK_TestTable]
PRIMARY KEY CLUSTERED ([Id] ASC)
) ON [PRIMARY]
GO
合并查询
MERGE INTO TestTable AS Target
USING (VALUES(NULL)) AS Source(SomeText) ON Target.SomeText = Source.SomeText
WHEN MATCHED THEN
UPDATE SET Target.Counter = Target.Counter + 1
WHEN NOT MATCHED THEN
INSERT (SomeText) VALUES(Source.SomeText);
如果匹配,则计数器加 1。如果不匹配,则插入新行。两次运行查询时,结果是两行,这不是我在 ansi_nulls 关闭时所期望的。
如果我将值 NULL 更改为 'test',则匹配工作正常,例如
使用(值(NULL))=>使用(值('test'))
使用合并时是否有一些特殊行为可以解释这一点?还是sql server的bug?
注意:我不是在寻找使用 ISNULL(...) 解决方案或类似解决方案的解决方法。这样我就无法确保有效使用匹配字段的索引。最初的问题是关于与多个匹配字段的合并,其中多个匹配字段可能碰巧为空。
【问题讨论】:
-
最好不要使用
SET ANSI_NULLS OFF,它已被弃用。根据documentation:“在 SQL Server 的未来版本中,ANSI_NULLS 将为 ON,任何显式将该选项设置为 OFF 的应用程序都会产生错误。避免在新的开发工作中使用此功能,并计划修改当前使用此功能的应用程序。” 您实际上想在这里实现什么?如果您需要将NULL与NULL进行比较,请使用A.Column IS NULL and B.Column IS NULL -
MERGE 语句有很多问题,Aaron Bertrand 在这里记录了这些问题:mssqltips.com/sqlservertip/3074/… 我不知道您的具体问题是否包括在这里,但我仍然鼓励您避免使用合并。
-
我正在尝试以这种方式使用 MERGE:MERGE INTO... ... ON Target.Field1 = Source.Field1 AND Target.Field2 = Source.Field2 AND Target.Field3 = Source.Field3 ...我需要这个匹配来支持空匹配和非空匹配。我知道我可以这样做: If ( (Target.Field1 = Source.Field1) OR (Target.Field1 IS NULL AND Source.Field1 IS NULL) ) @larnu 但是这样我预测查询计划在所有情况下都不是有效的与 field1、field2 和 field3 的空值和非空值混合。在这种情况下,您如何建议有效匹配?
-
@JoeStefanelli 是的,我知道这一点,只需要在用简单的 SELECT + UPDATE/INSERT 语句替换之前确认这一点。
-
SET ANSI_NULLS ON affects a comparison only if one of the operands of the comparison is either a variable that is NULL or a literal NULL. If both sides of the comparison are columns or compound expressions, the setting does not affect the comparison.
标签: sql-server tsql merge sql-server-2008-r2 ansi-nulls