就像你们中的许多人之前所做的那样,我正在尝试重写 .NET 应用程序以与 SQLBulkCopy 一起使用,以便在将数据写入数据库时获得所需的性能优势。
我知道 SQLBulkCopy 只能执行插入,如果我也想使用更新,我将需要一个临时表并将该表合并到永久表。我以前在 SQL 中使用过 MERGE,所以我想我能弄清楚这一点。
我见过使用事务来使其更加安全的示例......但是您什么时候清理暂存表?就在 MERGE 语句之后?类似“如果存在则删除”之类的东西?
但是我不明白的是:MERGE 语句如何知道要合并哪条记录? (假设交易可能失败并留下未处理的记录)
示例 |ID |名称 |姓氏 |城市 | |---|--------|---------|----------| |1 |巴特 |辛普森|斯普林菲尔德 | |1 |博尔特 |辛普森|斯普林菲尔德 | |2 |丽莎|桑普森|斯普林菲尔德 | |2 |丽莎|辛普森|斯普林菲尔德 | |3 |荷马 |辛普森|斯普林菲尔德 |
我知道您永远无法合并此记录,因为您不知道首选哪些记录。就我而言,是最近的一个,因此我可以添加一个额外的列 LastUpdatedOn,其中包含名称所怀疑的时间戳。
但是我如何告诉 MERGE 使用最新的行并删除其他行,以防止下次运行时被旧数据覆盖。
或者还有其他更简单的方法吗?我是不是忽略了什么?
将 SQLBulkCopy 与 MERGE 结合使用来处理插入和更新确实可以提高性能,但管理过时或冲突的记录可能很棘手。添加 LastUpdatedOn 列来识别最新记录的做法是正确的。
您可以采取以下方法:
暂存表设置:正如您所提到的,暂存表将临时保存所有传入记录。每条记录都应具有唯一标识符(例如 ID)和 LastUpdatedOn 时间戳,以区分同一记录的新旧版本。
MERGE 语句逻辑:在 MERGE 语句中,您可以使用 LastUpdatedOn 字段来确定要保留哪条记录:
MERGE INTO PermanentTable AS target
USING (SELECT * FROM StagingTable) AS 源 ON 目标.ID = 源.ID 匹配时且 source.LastUpdatedOn > target.LastUpdatedOn 然后更新设置 目标.名称 = 源.名称, 目标.姓氏 = 源.姓氏, 目标城市 = 来源城市, 目标.LastUpdatedOn = 源.LastUpdatedOn 当目标不匹配时 然后插入(ID、姓名、姓氏、城市、上次更新时间) 值(源.ID、源.名称、源.姓氏、源.城市、源.LastUpdatedOn);