MERGE: ВСТАВИТЬ в МАТЧ - PullRequest
0 голосов
/ 19 мая 2018

Я загружаю данные, в которых будут дубликаты с ранее загруженными данными.

Я успешно использую инструкцию MERGE для удаления дубликатов на основе номера транзакции.Предположительно, этого достаточно, но я бы хотел следить за тем, изменятся ли когда-либо подробности в конкретной транзакции.

С этой целью я добавил предложение when matched в merge с дополнительной вставкой, которая идентифицирует записькак дубликат.

Эта логика не должна срабатывать очень часто, поэтому я не слишком обеспокоен тем, что этот метод (если он работает) будет сообщать один и тот же дубликат несколько раз.

Когда я готовлю этот кодЯ получаю это сообщение об ошибке:

An action of type 'INSERT' is not allowed in the 'WHEN MATCHED' clause of a MERGE statement.

Есть ли способ получить дубликат записи для вставки в эту таблицу или другую таблицу с помощью инструкции MERGE?

Я открыт для других решений,но мне бы очень хотелось найти способ сделать это с помощью оператора MERGE, потому что это меньше всего повлияло бы на мой код.

MERGE INTO dbo.TransactionDetail as t
USING (SELECT @TransNr --bigint
             ,@Detail  -- [VARCHAR](50) NOT NULL
      ) as s
      ([TranNr]
      ,[Detail]
      )
   on t.TranNr = s.TranNr and t.CHANGED_RECORD = 0
 when not matched then
      INSERT (CHANGED_RECORD
         ,[TranNr]
             ,[Detail]
             )
      VALUES(0, s.TranNr, s.Detail)
/* Adding this does not allow statement to be prepared....
 when matched and s.Detail <> t.Detail
 then
      INSERT (CHANGED_RECORD
         ,[TranNr]
             ,[Detail]
             )
      VALUES(1, s.TranNr, s.Detail)
*/
;

1 Ответ

0 голосов
/ 19 мая 2018

Вы можете использовать оператор INSERT, например:

INSERT INTO dbo.TransactionDetail (CHANGED_RECORD,TranNr,Detail)
SELECT  CASE WHEN EXISTS (
            SELECT * FROM dbo.TransactionDetail 
            WHERE TranNr=@TransNr AND CHANGED_RECORD=0 AND Detail<>@Detail
        ) THEN 1 ELSE 0 END AS CHANGED_RECORD,
        @TransNr AS TranNr, @Detail AS Detail
WHERE NOT EXISTS (
    SELECT * FROM dbo.TransactionDetail 
    WHERE TranNr=@TransNr AND CHANGED_RECORD=0 AND Detail=@Detail
)

Вставка будет пропущена, если строка с CHANGED_RECORD=0 имеет такую ​​же детализацию.Однако, если такая же деталь будет найдена в другой строке с CHANGED_RECORD=1, будет вставлен новый дубликат.Чтобы избежать этого, удалите условие AND CHANGED_RECORD=0 из подзапроса WHERE NOT EXISTS.

Вы также можете создать уникальный отфильтрованный индекс, чтобы обеспечить уникальность для строк, которые имеют CHANGED_RECORD=0:

CREATE UNIQUE INDEX IX_TransactionDetail_Filtered 
ON TransactionDetail (TranNr) /*INCLUDE (Detail)*/ WHERE CHANGED_RECORD=0

Предложение INCLUDE (Detail) может также незначительно улучшить производительность запросов, которые ищут Detail строк, имеющих CHANGED_RECORD=0 (за счет некоторого дополнительного дискового пространства и небольшого снижения производительности при обновленииDetail столбец существующих строк).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...