OUTPUT из MERGE только затертых записей

Daba
Дата: 05.05.2015 15:40:23
Я небольшой поклонник MERGE но тут как-то показалось к месту.
Нужно вставить/изменить/стереть записи из таблицы согласно полученному файлу. Соотношение новых/измененых/ненужных записей примерно 50000/100/5. Измененные и стертые записи нужно перебросить в архив. Для этого собиралься использовать OUTPUT, но тут неприятность: возвращаются все строчки - и новые, и измененные, независимо от того что я прошу только deleted.* ... И даже если я могу их диференцировать с помощью $action, сбросить во временную табличку - слабое утешение - не хочу строить и перетаскивать заранее бесполезую дату.
Подскажите, есть красивый обход?
Гавриленко Сергей Алексеевич
Дата: 05.05.2015 15:54:15
Разбить на 2 merge.
iap
Дата: 05.05.2015 16:48:00
Отсюда https://msdn.microsoft.com/ru-ru/library/bb510625(v=sql.100).aspx
Вас не устраивает пример Г?
iap
Дата: 05.05.2015 17:11:41
iap
Отсюда https://msdn.microsoft.com/ru-ru/library/bb510625(v=sql.100).aspx
Вас не устраивает пример Г?
То есть, там рассказывается про INSERT из SELECTа из подзапроса
с MERGE и OUTPUT с возможностью фильтровать INSERT с помощью WHERE :))
Daba
Дата: 05.05.2015 17:15:29
Гавриленко Сергей Алексеевич,
где первый будет вставлять а второй изменять и стирать?
Конечно можно, но как-то левовато, весь смысл "атомарной" операции пропадает. Т.е. два раза нужно цеплятся к основной таблице, добавлять транзакцию и т.п. Я правильно понял?
Гавриленко Сергей Алексеевич
Дата: 05.05.2015 17:26:28
Daba
Гавриленко Сергей Алексеевич,
где первый будет вставлять а второй изменять и стирать?
Конечно можно, но как-то левовато, весь смысл "атомарной" операции пропадает. Т.е. два раза нужно цеплятся к основной таблице, добавлять транзакцию и т.п. Я правильно понял?
Да. Решайте, что вам проще. Делать два merge, или выбирать свои пять удалений 60к записей.
a_voronin
Дата: 05.05.2015 17:44:27
WHERE Action = 'DELETE';

USE AdventureWorks;
GO
CREATE TABLE Production.UpdatedInventory
    (ProductID INT NOT NULL, LocationID int, NewQty int, PreviousQty int,
     CONSTRAINT PK_Inventory PRIMARY KEY CLUSTERED (ProductID, LocationID));
GO
INSERT INTO Production.UpdatedInventory
SELECT ProductID, LocationID, NewQty, PreviousQty 
FROM
(    MERGE Production.ProductInventory AS pi
     USING (SELECT ProductID, SUM(OrderQty) 
            FROM Sales.SalesOrderDetail AS sod
            JOIN Sales.SalesOrderHeader AS soh
            ON sod.SalesOrderID = soh.SalesOrderID
            AND soh.OrderDate BETWEEN '20030701' AND '20030731'
            GROUP BY ProductID) AS src (ProductID, OrderQty)
     ON pi.ProductID = src.ProductID
    WHEN MATCHED AND pi.Quantity - src.OrderQty >= 0 
        THEN UPDATE SET pi.Quantity = pi.Quantity - src.OrderQty
    WHEN MATCHED AND pi.Quantity - src.OrderQty <= 0 
        THEN DELETE
    OUTPUT $action, Inserted.ProductID, Inserted.LocationID, Inserted.Quantity AS NewQty, Deleted.Quantity AS PreviousQty)
 AS Changes (Action, ProductID, LocationID, NewQty, PreviousQty) WHERE Action = 'DELETE';


либо OUTPUT DELETED.*;
Daba
Дата: 05.05.2015 18:24:27