删除vs回滚策略 - ETL加载

时间:2016-12-07 11:44:43

标签: sql-server etl sql-server-2016

我按以下方式将数据加载到表中:

DECLARE @srcRc INT;
DECLARE @dstRc INT;

SET @srcRc = ( SELECT COUNT(*) FROM A )

INSERT  INTO t
        (Col1
        ,Col2
        ,Col3
        )
        SELECT  A.Col1
               ,A.Col2
               ,B.Col3
        FROM    A
                JOIN B
                    ON A.Id = B.Id;

SET @dstRc = @@ROWCOUNT

现在我正在比较变量@srcRc@dstRcROWCOUNT必须相同。如果不是,则需要删除插入的行。

Q1:回滚插入行的最佳策略是什么?

我有几个想法:

1)如果rowcount不匹配,则在事务和回滚中运行load 2)将标志列(位)添加到名为toBeDeleted的目标表中,运行加载,如果rowcount不匹配,请更新toBeDeleted1值以将其标记为候选删除。然后在批处理模式下删除(while循环)。
或者不删除它们,但在使用t表时始终从查询中排除删除候选项 3)在插入行之前,首先比较行计数。如果不匹配,请不要开始加载。

DECLARE @srcRc INT;
DECLARE @dstRc INT;
SET @srcRc = ( SELECT   COUNT(1) FROM A );
SET @dstRc = ( SELECT   COUNT(1) FROM A JOIN B ON A.Id = B.Id );

Q2:对于更高的行数,更好的解决方案,比如10-100 mil。? 问题3:或者类似案例有更好的策略吗?

1 个答案:

答案 0 :(得分:0)

好的,假设:

当表A和B的内容可能已更改

时,您需要在稍后的某个日期工作

在T中可能还有其他行,您不想将其作为回滚的一部分删除。

然后你必须保留一个你插入的行的列表,因为你无法从A和B中可靠地重新生成该列表而你不能删除T中的所有内容

你可以用两种方式做到这一点

  • 更改您的导入,以便首先将行插入导入表格,让导入表格保持不变,直到您确定不再需要它为止。

  • 在T [importId]中添加一个额外的列,您可以在其中添加唯一标识值

显然,第一种策略使用了更多的磁盘空间。因此,保留数据的时间越长,数据越多,额外列的外观就越好。

另一种选择是单独生成导入数据列表,并将事务sql作为批量插入,将所有数据硬编码到sql中。

这适用于小型列表,初始设置数据等。

编辑:

从你的评论中听起来你不想要回滚本身。但是围绕导入过程应用业务逻辑的最佳方式。

在这种情况下,你的第三个答案是最好的。当您知道源数据不正确时,请不要进行导入。