从datatable复制新记录并识别旧记录中的更改

时间:2012-10-09 09:27:16

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

假设有两个表:Remote_tableMy_table

Remote_table有6列:

PROJECT   JOB_TYPE   MONTH  YEAR**       HOURS     IS_DELETED
134393     70         1       2013      30     0
134393     70         2       2013      50     0
134393     70         3       2013      80     0
134393     70         10      2012      10     0
134393     70         11      2012      0      0
134393     70         12      2012      15     0

My_tableremote_table的副本。

我尝试通过此查询仅复制remote_table中的新记录:

SELECT    *
FROM [remote_DB].[LudanProjectManager].[dbo].Remote_table            
EXCEPT           
SELECT    *
FROM My_table

它工作正常,但是当我在小时列的remote_table上进行了更改时,我遇到了重复的主键异常。

有人可以想到一种方法只复制remote_table的新记录,是否对旧记录进行了更改,识别它们并更新my_table以对应?

3 个答案:

答案 0 :(得分:2)

由于您使用的是SQL Server 2008,因此可以使用MERGE

MERGE INTO My_table AS TGT
USING Remote_table AS SRC
  ON TGT.PROJECT = SRC.PROJECT, -- This is the matching condition. 
     TGT.YEAR    = SRC.YEAR,
   ---
WHEN NOT MATCHED THEN
  INSERT(PROJECT, JOB_TYPE, MONTH, YEAR, HOURS, IS_DELETED)
  VALUES(SRC.PROJECT, SRC.JOB_TYPE, SRC.MONTH, SRC.YEAR, SRC.HOURS,
         SRC.IS_DELETED);

请注意:

  • 匹配和不匹配的行是根据ON子句中指定的编码确定的,您可能需要使用额外条件, TGT.Year = SRC.TGT, ..来限制匹配的行,或者仅在{{1}上匹配}字段仅使用PROJECT
  • 您必须以分号结束ON TGT.PROJECT = SRC.PROJECT语句。这是强制性的。
  • MEREGE语句中没有INSERT,因为目标表的名称已在INTO TableName子句中定义。

答案 1 :(得分:1)

试试这个:

 MERGE INTO My_table T
USING 
    Remote_table R
    ON T.PROJECT    = R.PROJECT   
WHEN MATCHED THEN
    UPDATE SET
       T.JOB_TYPE=R.JOB_TYPE
       T.MONTH  =R.MONTH  
       T.YEAR =R.YEAR
       T.HOURS =R.HOURS
       T.IS_DELETED=R.IS_DELETED
WHEN NOT MATCHED THEN
    INSERT (T.PROJECT,T.JOB_TYPE,T.MONTH,T.YEAR,T.HOURS,T.IS_DELETED)
    VALUES (R.PROJECT,R.JOB_TYPE,R.MONTH,R.YEAR,R.HOURS,R.IS_DELETED);  

答案 2 :(得分:0)

识别新内容:

SELECT * FROM [remote_DB].[LudanProjectManager].[dbo].Remote_table RT
WHERE NOT EXISTS
(
   SELECT 1 FROM My_table MT WHERE MT.PROJECT=RT.PROJECT
)

识别变化:

SELECT * FROM [remote_DB].[LudanProjectManager].[dbo].Remote_table RT
INNER JOIN My_table MT ON RT.PROJECT=MT.PROJECT
WHERE RT.JOB_TYPE   <> MT.OB_TYPE
OR    RT.MONTH      <> MT.MONTH  
OR    RT.YEAR       <> MT.YEAR
OR    RT.HOURS      <> MT.HOURS 
OR    RT.IS_DELETED <> MT.IS_DELETED