MSSQL MERGE - Попытка указания значения NULL

Выполняю запрос в котором точно нет дублей и пустых полей.
Он идеально работает если указать SELECT TOP 250. Все происходит успешно.
Если указать SELECT TOP 251 или вообще убрать TOP - выпадает ошибка "Попытка указания значения NULL для столбца, который не может содержать значение NULL." Строка с 251 номером валидная, все поля не пустые.
Всего в таблице чуть меньше 100 000строк.
Если делать простой INSERT - проблем нет, отрабатывает.
Где искать?
Замечала на подобной конструкции в других запросах - если число полей меньше (например, 3шт), а кол-во строк гораздо больше (например, 5000шт) - проблем нет.

MERGE dbo.tableTarget AS target
USING(
    SELECT top 251
         tData.field1
        ,tData.field2
        ,tData.field3
        ,tData.field4
        ,tData.field5
        ,tData.field6
        ,tData.field7
        ,tData.field8
        ,tData.field9
    FROM dbo.tableSource AS tData
    WHERE 1 = 1
        AND tData.isValid = 1
) AS source
ON(
    target.field1= source.field1
    AND target.field2 = source.field2
    AND target.field4 = source.field4
    AND target.field5 = source.field5
)
WHEN MATCHED
THEN
    UPDATE
    SET
         target.field2 = source.field2 
        ,target.field3 = source.field3 
        ,target.field4 = source.field4 
        ,target.field5 = source.field5 
        ,target.field6 = source.field6 
        ,target.field7 = source.field7 
        ,target.field8 = source.field8 
        ,target.field9 = source.field9
WHEN NOT MATCHED
THEN
    INSERT(
         field1
        ,field2 
        ,field3 
        ,field4 
        ,field5 
        ,field6 
        ,field7 
        ,field8 
        ,field9
    ) VALUES(
         source.field1
        ,source.field2 
        ,source.field3 
        ,source.field4 
        ,source.field5 
        ,source.field6 
        ,source.field7 
        ,source.field8 
        ,source.field9
    )
OUTPUT $action, inserted.*, deleted.*; 

Изначально таблица - приемник пустая.

Дополнение. Таблица системно-версионированная, заметили проблему в некластеризованном индексе на историчной таблице. Если заменить на колоноччный индекс - проблем нет. Непонятно - при первичной вставке в историчную таблицу ничего не съезжает, нуловых полей по индексу нет... почему так?


Ответы (1 шт):

Автор решения: Герман Борисов

В таких ситуациях я обычно начинаю с того, чтобы методом половинного деления найти строку, на которой всё ломается.

Как правило в таблицах такого размера есть или уникальный ID или более-менее монотонно возрастающая дата.

Допустим у нас в таблице записи с 01.01.2008 по сегодня. Примерно половина будет 01.01.2014

Выполняем запрос сначала добавляя в source дополнительное условие and tData.DateField <= '2014-01-01', затем and tData.DateField > '2014-01-01'

На одном из двух сломается. Еще вдвое сокращаем диапазон.

Допустим сломалось на первом, тогда условия будут and tData.DateField <= '2011-01-01' и and tData.DateField > '2011-01-01' and tData.DateField > '2014-01-01'

И так далее примерно за двадцать шагов от 100000 останется одна запись.

Далее внимательно смотреть на запись.

→ Ссылка