Я создаю веб-приложение ASP.net, которое получает файл CSV от пользователя, загружает файл на сервер, TempHoldingTable
копирует данные в TempHoldingTable
. Затем код вызывает хранимую процедуру, которая содержит оператор Merge
для копирования данных из TempHoldingTable
в соответствующие несколько таблиц. Я использую SQL Server 2008 R2.
У меня есть несколько операторов Merge
в хранимой процедуре, я скопировал только один из них:
MERGE Client AS C
USING (SELECT ClientID, Value1, Value2, Value3, Row_Number() Over (PARTITION BY ClientID order by Date desc) as Rno
FROM TempHoldingTable) AS T ON (C.ClientID = T.ClientID)
WHEN NOT MATCHED BY TARGET AND T.Rno = 1
THEN
INSERT(ClientID, Value1, Value2, Value3)
VALUES(T.ClientID, Value1, Value2, Value3)
OUTPUT $action, inserted.*, deleted.*;
CSV-файл загружается каждый месяц, поэтому позволяет предположить, что первый файл был загружен в январе 2014 года и имеет следующие данные:
ClientID Value1 Value2 Value3
111 abc def ghi
222 jkl mno pqr
Затем пользователь загружает второй файл в феврале 2014 года и имеет следующие данные:
ClientID Value1 Value2 Value3
111 aaa bbb ghi
222 jkl mno pqr
333 sss ttt uuu
Процедура слияния обновит таблицу клиента для ClientID 111, потому что значение1 и значение2 были изменены, оставить ClientID 222 как есть и вставить новую строку для ClientID 333.
Мой вопрос заключается в том, если пользователь решает удалить файл в феврале 2014 года, как я могу отслеживать и возвращать изменения, которые были вызваны из-за загрузки в феврале 2014 года, чтобы таблица Client содержала те же данные, что и после загрузки в январе 2014 года.
Обратите внимание, что это отслеживание должно выполняться для каждой загрузки, так что всякий раз, когда пользователь удаляет файл, база данных возвращается к той же позиции, что и в предыдущем месяце.
Мой второй вопрос заключается в том, как изменить инструкцию Merge для обновления значений, если существует ClientID, и любой столбец имеет другое значение, чем предыдущее.
Спасибо за ваше терпение, прочитав все это, и любая помощь будет принята с благодарностью.
Ответ на Q1: исходя из размера ваших данных, я думаю, что создание механизма отслеживания ( Change tracking /CDC
) будет чрезмерным (IMO). Возможно, вы, возможно, настроили процесс, который (перед применением файла) выталкивает данные из каждой из 8 таблиц в другой набор таблиц (версированный набор данных), который хранит его в зависимости от месяца / года. Если пользователь решает удалить определенный файл месяца, вытащите предыдущий набор из набора данных версий и примените его к активным таблицам.
Не забудьте настроить процесс очистки для версии dataset, хотя, может быть, это может стать довольно большим сверхурочным.
Ответ Q2: вы можете использовать предложение When Matched
MERGE Client AS C
USING (SELECT ClientID, Value1, Value2, Value3, Row_Number() Over (PARTITION BY ClientID order by Date desc) as Rno
FROM TempHoldingTable) AS T ON (C.ClientID = T.ClientID)
WHEN NOT MATCHED BY TARGET AND T.Rno = 1
THEN
INSERT(ClientID, Value1, Value2, Value3)
VALUES(T.ClientID, Value1, Value2, Value3)
WHEN MATCHED
THEN UPDATE SET C.Value1 = T.Value1
, C.Value2 = T.Value2
, C.Value3 = T.Value#3
OUTPUT $action, inserted.*, deleted.*;