表的增量更新

时间:2015-10-13 04:27:44

标签: sql sql-server tsql integration etl

我是使用SSIS包从SQL Server复制数据到Oracle,我希望通过增量更新来提高复制的性能。

我的想法是:

  1. 附加表的新记录。(删除它们然后追加)
  2. 删除"已删除"记录
  3. 代码:

     drop table A1
     drop table A2
    
     --Old Table
     create Table A1(id int,
                     a1 int, a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int)
    
     --New Table
     create Table A2(id int,
                     a1 int, a2 int, a3 int, a4 int, a5 int, a6 int, a7 int, a8 int)
    
     insert into A1 (id, a1, a2, a3, a4, a5, a6, a7, a8) 
     values (1,1,2,3,4,5,6,7,8), (2,2,2,5,4,2,6,2,8), (3,3,2,5,4,5,4,3,8),
            (4,3,1,3,4,5,7,3,8)
    
     insert into A2 (id, a1, a2, a3, a4, a5, a6, a7, a8) 
     values (1,2,2,3,4,5,6,7,8), (2,2,2,5,4,2,6,2,8), (3,3,2,5,4,5,4,3,8)
    --1) Changed values  
    
     select * from a2
     except
     select * from a1;
    
     --2)  "Deleted" Values. If I Have primary key in A1,A2 the result is simply get by query
     select a1.* 
     from A1 
     left join A2 on a2.id = a1.id 
     where a2.id is null
    

    但在我的实际情况中,我的桌子上没有主键。如何在没有主键加入的情况下以另一种方式实现2点?

    查询结果:

    id  a1  a2  a3  a4  a5  a6  a7  a8
    1   2   2   3   4   5   6   7   8
    
    
    id  a1  a2  a3  a4  a5  a6  a7  a8
    4   3   1   3   4   5   7   3   8
    

2 个答案:

答案 0 :(得分:2)

使用MERGE语句,您可以执行INSERT,UPDATE&在单个操作中删除,它是增量负载的理想选择。

示例代码:

    MERGE A2 AS target
    USING (SELECT * FROM A1) AS source 
    ON (target.Id = source.Id AND target.a1 = Source.a1...) -- More join condition
    WHEN MATCHED THEN 
        UPDATE SET a2 = source.a2, a3 = source.a3 ------ more columns
WHEN NOT MATCHED THEN
    INSERT (Id, A1, a1, a2....)
    VALUES (source.Id, source.a1, source.a2.....) 

WHEN NOT MATCHED BY SOURCE
        THEN DELETE 
END;

MERGE语句还提供了捕获插入,删除和更新记录的灵活性(如果您需要它们用于记录目的),但在您确实需要该信息之前我不建议使用它们。

在上面的查询中,您可以保留要比较的列

  

ON(target.Id = source.Id AND target.a1 = Source.a1 ...) - 更多加入

SSIS

您可以使用LOOKUP转换查找匹配和无匹配记录,然后插入或删除记录。 任何情况下,如果您正在考虑将源表与目标和更新进行比较中的所有列都没有意义。

答案 1 :(得分:0)

您可以使用基于日志文件而不是查询的CDC或其他日志传送机制。如果您仍想将SSIS用于查询 -

您是否曾尝试在SQL Server上使用 rowversion 来查找差异,但肯定会比 更快

  

从a2中选择*,其中rowversion> @lastmaxrowversion;

要找到删除是一项艰巨的任务,您可以做的最好的事情是

  

从不存在的a1中选择a1.id(从a2中选择前1 1)   a1.id = a2.id);

如果你可以添加一个for delete触发器并将id保存在一个非常好的表中。

  • 请记住,许多公司并不真正关心ETL过程中删除的记录,因为存储不再是一个案例。此外,现在您可以设计您的系统,不删除分区表归档或活动标志。无论如何,如果删除仍然很重要,可能会尝试为插入/更新与删除设置不同的间隔。例如,每10分钟检查一次插入/更新,每24小时删除一次。