【发布时间】:2013-11-26 22:37:08
【问题描述】:
我可以在 SQL Merge 上找到很多信息,但我似乎无法让它为我工作。这是正在发生的事情。
每天我都会将一个 Excel 文件上传到一个包含几千条记录的 Web 服务器,每条记录包含 180 列。这些记录既包含必须使用 INSERT 的新信息,也包含必须使用 UPDATE 的更新信息。要将信息获取到数据库,我使用 C# 将批量复制到临时 SQL 2008 表。我的计划是然后执行合并以将信息放入实时表中。临时表没有设置主键,但活动表有。最后,这就是我的 Merge 语句的样子:
MERGE Table1 WITH (HOLDLOCK) AS t1
USING (SELECT * FROM Table2) AS t2
ON t1.id = t2.id
WHEN MATCHED THEN
UPDATE SET (t1.col1=t2.col1,t1.col2=t2.col2,...t1.colx=t2.colx)
WHEN NOT MATCHED BY TARGET THEN
INSERT (col1,col2,...colx)
VALUES(t2.col1,t2.col2,...t2.colx);
即使包含 HOLDLOCK,我仍然收到错误 Cannot insert duplicate key in object。从我在线阅读的内容来看,HOLDLOCK 应该允许 SQL 读取主键,但在任务执行之前不执行任何插入或更新。我基本上是在学习如何即时使用 MERGE,但是我必须启用一些东西才能让 SQL 2008 使用 MERGE 锁吗?
【问题讨论】:
-
我的建议:用老方法做。 MERGE 可能看起来不错,但它有很多问题。 mssqltips.com/sqlservertip/3074/…
-
表的定义是什么?它有不止一个独特的约束吗?来源是否也有重复?
-
SQL 语句“并行”有效地应用所有行更改 - 如果源表中有两行具有相同的 PK 值,而目标中没有具有该 PK 值的行,
MERGE将尝试插入 两行 行,然后失败。 -
@AaronBertrand 我害怕那个。稍后我会试一试并发布结果。
-
不,你错了。
HOLDLOCK在这里只是防止在检查行不存在和尝试插入之间的 不同 事务中插入行。它不会对源中的任何重复键进行重复数据删除。如果有多个具有相同的t2.id,您要插入哪一行?
标签: sql-server-2008 merge