【发布时间】:2015-04-05 17:20:26
【问题描述】:
我正在创建一个 ASP.net Web 应用程序,它接收来自用户的 CSV 文件,将文件上传到服务器,将数据批量复制到 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 年 1 月上传的,它有以下数据:
ClientID Value1 Value2 Value3
111 abc def ghi
222 jkl mno pqr
然后用户在 2014 年 2 月上传了第二个文件,它有以下数据:
ClientID Value1 Value2 Value3
111 aaa bbb ghi
222 jkl mno pqr
333 sss ttt uuu
Merge 例程将更新 ClientID 111 的客户端表,因为 value1 和 value2 已更改,保持 ClientID 222 不变,并为 ClientID 333 插入新行。
我的问题是,如果用户决定删除 2014 年 2 月的文件,我如何跟踪和恢复由于 2014 年 2 月上传而导致的更改,以便客户端表包含与 2014 年 1 月上传后相同的数据。
请注意,每次上传都需要进行此跟踪,这样每当用户删除文件时,数据库就会恢复到与上个月相同的位置。
我的第二个问题是如果存在 ClientID 并且任何列的值与前一个不同,如何修改 Merge 语句以更新值。
感谢您耐心阅读所有这些内容,我们将不胜感激。
【问题讨论】:
-
因此,如果用户在哪里删除 Feb2014 文件,您将恢复到 2014 年 1 月的设置,然后重播 3 月、4 月、5 月等的文件……对吗?
-
用户只能以相反的顺序删除文件,所以如果最后一个文件是在三月上传的,那么他们可以在删除二月文件之前删除三月文件。当他们删除 3 月文件时,数据将恢复为 2 月文件上传时的状态。当他们删除 2 月文件时,数据将恢复为 1 月。一旦我们有了 1 月数据,用户将被允许再次上传 2 月文件,然后是 3 月,依此类推。
-
你的数据集有多大?
-
每个文件可以包含 20K 到 30K 行和 100 多列。数据被批量复制到临时表,然后跨 8 个表移动。很多行将包含相同的数据,这就是我使用 Merge 表的原因,这样我就不需要更改这些记录的数据。
标签: sql merge sql-server-2008-r2 sqlbulkcopy