SSIS Foreach通过表,插入另一个表并删除源行

时间:2013-03-19 15:42:07

标签: foreach ssis insert

我有一个SSIS例程,它从一个非常动态的表中读取,并在截断原始源表之前,将它找到的任何行插入到不同数据库的表中。

由于源表的动态特性,这种截断不会令人惊讶地导致行无法进入第二个数据库。

仅删除已迁移的行的最佳方法是什么?

源表上有一个标识列,但不会迁移它。

我无法更改任何一种表架构。

2 个答案:

答案 0 :(得分:4)

一个可能听起来很愚蠢但可行的选项是首先删除并使用OUTPUT子句。

control flow setup

我创建了一个简单的控制流程,为我填充表格。

IF EXISTS
(
    SELECT 1 FROM sys.tables AS T WHERE T.name = 'DeleteFirst'
)
BEGIN
    DROP TABLE dbo.DeleteFirst;
END

CREATE TABLE dbo.DeleteFirst
(
    [name] sysname
);

INSERT INTO
    dbo.DeleteFirst
SELECT
    V.name
FROM
    master.dbo.spt_values V
WHERE
    V.name IS NOT NULL;

dataflow

在我的OLE DB Source中,不是使用SELECT,而是删除要沿管道传输的数据并输出DELETED虚拟表。有些喜欢

DELETE
    DF
OUTPUT
    DELETED.*
FROM
    dbo.DeleteFirst AS DF;

results

它有效,它有效!

答案 1 :(得分:1)

一种选择是创建一个表来记录处理过的记录的标识,然后创建一个单独的包(或数据流)来删除这些记录。如果您已经在某处记录了处理过的记录,那么您可以在那里添加标识 - 否则,创建一个新表来存储数据。

第二种选择:如果您试图避免创建其他表,则将记录选择和记录处理分为两个阶段。从广义上讲,您将在控制流中选择所有记录,然后在数据流中逐个处理它们。 具体来说:

  1. 创建一个Object类型的变量来存储你的记录列表,另一个变量匹配你的身份类型(可能是int)来存储'当前记录标识'。
  2. 在控制流程中,添加一个执行SQL任务,该任务使用查询来构建要处理的标识值列表,然后将它们存储到记录列表变量中。
  3. 添加Foreach循环容器以处理该列表; foreach任务会将当前记录标识符加载到您在上面定义的第二个变量中。
  4. 在foreach任务中,添加数据流以复制该单个记录,然后将其从源中删除。
  5. 网上有很多这样的例子;例如this one来自尊敬的Jamie Thomson,或this one,其中包含更多细节。

    请注意,您没有谈论数据的规模;如果你有非常多的记录,第一个建议可能是一个更好的选择。请注意,在这两种情况下,您都会失去表截断的优势(因为您使用的是标准delete调用)。