我已经阅读了在当前会话中使用“SET ANSI_NULLS OFF”以便能够将 NULL = NULL 评估为 true,例如,以下示例显示了 ANSI_NULLS ON 和 ANSI_NULLS OFF 之间的区别:
问题一:
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中的错误?
注意:我不是在寻找使用 ISNULL(...) 解决方案或类似解决方案的解决方法。这样我就无法确保有效使用匹配字段的索引。最初的问题是关于与多个匹配字段的合并,其中多个匹配字段可能碰巧为空。