Оператор T-SQL MERGE не вставляет новую запись - что не так с моим кодом? - PullRequest
0 голосов
/ 29 октября 2018

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

Чтобы увидеть, как работает обновление, измените цвет в объявлениях переменной DEBUG, чтобы он совпадал со значением в операторе вставки.

BEGIN TRY 
    DROP TABLE #adr_test
END TRY
BEGIN CATCH
    -- nothing to drop
END CATCH

CREATE TABLE #adr_test
(
    style NVARCHAR(5)
    ,size_id INT
    ,colour_id INT
    ,cost MONEY
)

INSERT INTO #adr_test (style, size_id, colour_id, cost) 
VALUES ('ADR01', 100, 101, 99.99)

/*DEBUG*/
DECLARE @style NVARCHAR(5) = 'ADR01'
DECLARE @sizeid INT = 100
DECLARE @colourid INT = 999
DECLARE @ctncost MONEY = 1.50
/*END DEBUG*/

MERGE #adr_test AS Tgt
USING (SELECT style, size_id, colour_id, cost
       FROM #adr_test                           
       WHERE style = @style
         AND size_id = @sizeid
         AND colour_id = @colourid) AS Src ON Src.style = Tgt.style
                                           AND Src.size_id = Tgt.size_id
                                           AND Src.colour_id = Tgt.colour_id

WHEN MATCHED AND Tgt.cost <> @ctncost 
   THEN
      UPDATE SET Tgt.cost = @ctncost

WHEN NOT MATCHED BY TARGET 
   THEN 
      INSERT (style, size_id, colour_id, cost)
      VALUES (@style, @sizeid, @colourid, @ctncost);


SELECT * FROM #adr_test

1 Ответ

0 голосов
/ 29 октября 2018

Чтобы уточнить ответы RBarry Young и Code Different, NOT MATCHED сравнивает то, что находится в ИСТОЧНИКЕ, с тем, что находится в цели. Поскольку я выбираю из той же таблицы с критериями фильтра, исходные результаты равны NULL, поэтому нечего НЕ СОГЛАСОВАТЬ. код в USING должен выглядеть следующим образом

SELECT
    style = @style
    ,colour_id = @colourid
    ,size_id = @sizeid
    ,cost = @ctncost

Таким образом, ИСТОЧНИК будет содержать набор результатов с одной записью, которая может или не может быть найдена в таблице TARGET. если это не соответствует, тогда вставка будет запущена.

Спасибо за вашу помощь, ребята.

...