我需要将大量数据从一个表复制到另一个表。如果数据已经存在,我需要更新它,否则我需要插入它。要复制的数据是使用WHERE条件选择的。数据有一个主键(最多12个字符的字符串)。
如果我只是插入数据,我会这样做
INSERT INTO T2 SELECT COL1, COL2 FROM T1 WHERE T1.ID ='I'
但我无法弄清楚如何进行INSERT / UPDATE。我一直看到对upserts和MERGE的引用,但MERGE似乎有问题,我无法弄清楚如何为多个记录进行upsert。
最佳解决方案是什么?
答案 0 :(得分:2)
如果你想避免合并(虽然你不应该害怕它),你可以做类似的事情
update t2
set col1 = t1.col1
,col2 = t1.col2
from t2
join t1
on t2.[joinkey] = t1.[joinkey]
where [where clause]
之后你没有
insert into t2(col1,col2)
select col1,col2 from t1
where not exists (select * from t2 where t1.[joinkey] = t2.[joinkey])
以这种方式首先更新匹配的那些,然后插入那些不匹配的那些。此外,如果您想要一次性使用它,您可以将其包装在交易中。
答案 1 :(得分:2)
通常称为UPSERT
操作。是的,你说合并有一些问题是正确的,所以远离它。
假设两个表中都有一个名为PK_Col
的主键列的简单方法就是这样......
BEGIN TRANSACTION;
-- Update already existing records
UPDATE T2
SET T2.Col1 = T1.Col1
,T2.Col2 = T1.Col2
FROM T2 INNER JOIN T1 ON T2.PK_COl = T1.PK_Col
-- Insert missing records
INSERT INTO T2 (COL1, COL2 )
SELECT COL1, COL2
FROM T1
WHERE T1.ID ='I'
AND NOT EXISTS (SELECT 1
FROM T2
WHERE T2.PK_COl = T1.PK_Col )
COMMIT TRANSACTION;
将整个UPSERT
操作包装在一个事务中。
答案 2 :(得分:1)
您可以使用IF EXISTS
之类的内容:
if exists (select * from table with (updlock,serializable) where key = @key)
begin
update table set ...
where key = @key
end
else
begin
insert table (key, ...)
values (@key, ...)
end
另一种解决方案是检查@@ROWCOUNT
UPDATE MyTable SET FieldA=@FieldA WHERE Key=@Key
IF @@ROWCOUNT = 0
INSERT INTO MyTable (FieldA) VALUES (@FieldA)