Я прочитал об использовании "SET ANSI_NULLS OFF" для текущего сеанса, чтобы иметь возможность оценить NULL = NULL в true, например, в следующем примере показано различие между ANSI_NULLS ON и ANSI_NULLS OFF:
QUERY A:
SET ANSI_NULLS OFF
IF(NULL = NULL)
SELECT 'NULL = NULL'
ELSE
SELECT 'NO MATCH'
РЕЗУЛЬТАТ: 'NULL = NULL'
QUERY B:
SET ANSI_NULLS ON
IF(NULL = NULL)
SELECT 'NULL = NULL'
ELSE
SELECT 'NO MATCH'
РЕЗУЛЬТАТ: «НЕТ МАТЧ»
Таким образом, это показывает разницу между настройками ВКЛ и ВЫКЛ.
Кажется, это также работает при использовании его в предложении where в стандартном операторе select.
ОДНАКО, похоже, что это не работает при слиянии, когда поля источника и цели равны нулю.
Воспроизведение простого сценария:
CREATETEST TABLE:
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 QUERY
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', совпадение будет работать нормально, например,
USING (VALUES (NULL)) => USING (VALUES ('test')) *
Существует ли какое-то особое поведение при использовании слияний, которое объясняет это?Или это ошибка в сервере sql?
ПРИМЕЧАНИЕ: я не ищу обходного пути, использующего ISNULL (...) - решение или что-то подобное.Таким образом, я не могу обеспечить эффективное использование индекса соответствующих полей.Первоначальная проблема касается слияния с несколькими полями совпадения, где несколько из них могут быть нулевыми.