将数据从表复制到表执行INSERT或UPDATE

时间:2015-08-17 11:46:32

标签: sql sql-server sql-server-2008

我需要将大量数据从一个表复制到另一个表。如果数据已经存在,我需要更新它,否则我需要插入它。要复制的数据是使用WHERE条件选择的。数据有一个主键(最多12个字符的字符串)。

如果我只是插入数据,我会这样做

INSERT INTO T2 SELECT COL1, COL2 FROM T1 WHERE T1.ID ='I'

但我无法弄清楚如何进行INSERT / UPDATE。我一直看到对upserts和MERGE的引用,但MERGE似乎有问题,我无法弄清楚如何为多个记录进行upsert。

最佳解决方案是什么?

3 个答案:

答案 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)