【问题标题】:UPSERT in SSISSSIS 中的 UPSERT
【发布时间】:2010-11-11 01:13:26
【问题描述】:

我正在编写一个在 SQL Server 2008 上运行的 SSIS 包。如何在 SSIS 中执行 UPSERT?

如果键不存在 插入 别的 如果数据更改 更新 万一 万一

【问题讨论】:

    标签: sql-server sql-server-2008 ssis upsert


    【解决方案1】:

    SQL Server 2008 - Using Merge From SSIS。我已经实现了类似的东西,而且非常容易。只需使用 BOL 页面Inserting, Updating, and Deleting Data using MERGE 就足以让我继续前进。

    【讨论】:

    • 我确认,MERGE 是要走的路。在 Kimball 上阅读:kimballgroup.com/html/08dt/…
    • kimballgroup 链接已失效。
    • SQL Server 的 MERGE 有(仍然有?)比 SQL Server 中的任何东西都多的错误。例如,它给人的印象是它在事务上是一致的。不是!
    • @Mitch 我从来没有觉得它在事务上是一致的。我从不假设任何事情都是如此,除非它明确表示。
    • @JohnSaunders:很多人都被这种假设抓住了,即使是专家。
    【解决方案2】:

    除了基于 T-SQL 的解决方案(甚至没有标记为 /)之外,您还可以使用具有合并连接的 SSIS 数据流任务,如 here(和 elsewhere)所述.

    关键部分是已排序源的合并连接中的完全外连接(如果您只想插入/更新而不是删除左外连接也可以)。

    然后是条件拆分以知道下一步该做什么:插入目标(这也是我的源),更新它(通过 SQL 命令),或从中删除(再次通过 SQL 命令)。

    1. 插入:如果 gid 仅在源中找到(左)
    2. 更新如果源和目标上都存在 gid
    3. DELETE:如果 gid 在源中未找到但在目标中存在(右)

    【讨论】:

      【解决方案3】:

      我建议你看看 Mat Stephen 在 SQL Server 的 upsert 上的博客。

      SQL 2005 - UPSERT: In nature but not by name; but at last!

      【讨论】:

      【解决方案4】:

      另一种在 sql 中创建 upsert 的方法(如果你有 pre-stage 或 stage 表):

      --Insert Portion
      INSERT INTO FinalTable
      ( Colums )
      SELECT T.TempColumns
      FROM TempTable T
      WHERE
      (
          SELECT 'Bam'
          FROM FinalTable F
          WHERE F.Key(s) = T.Key(s)
      ) IS NULL
      
      --Update Portion
      UPDATE FinalTable
      SET NonKeyColumn(s) = T.TempNonKeyColumn(s)
      FROM TempTable T
      WHERE FinalTable.Key(s) = T.Key(s)
          AND CHECKSUM(FinalTable.NonKeyColumn(s)) <> CHECKSUM(T.NonKeyColumn(s))
      

      【讨论】:

      • 这是在 SQL 2005 中执行此操作的好方法,但不要忘记用于删除数据的可选第 3 节。但是,SQL Server 2008 的 MERGE 语句具有类似的功能并且可能更快。
      【解决方案5】:

      多年来一直在使用的基本数据操作语言 (DML) 命令是更新、插入和删除。它们完全符合您的预期:Insert 添加新记录,Update 修改现有记录,Delete 删除记录。

      UPSERT 语句修改现有记录,如果记录不存在,则插入新记录。 UPSERT 语句的功能可以通过两组新的 TSQL 运算符来实现。这是两个新的

      EXCEPT
      INTERSECT
      

      除了:-

      返回除右侧查询之外未返回的查询左侧的任何不同值

      相交:- 返回由 INTERSECT 操作数左右两侧的查询返回的任何不同值。

      示例:- 假设我们有两个表表 1 和表 2

      Table_1 column name(Number, datatype int)
      ----------
      
      1
      2
      
      3
      4
      5
      
      Table_2 column name(Number, datatype int)
      ----------
      
      1
      2
      
      5
      
      SELECT * FROM TABLE_1 EXCEPT SELECT * FROM  TABLE_2 
      

      将返回 3,4,因为它存在于 Table_1 而不是 Table_2 中

      SELECT * FROM TABLE_1 INTERSECT SELECT * FROM  TABLE_2 
      

      将返回 1,2,5,因为它们存在于表 Table_1 和 Table_2 中。

      现在消除了复杂连接的所有痛苦:-)

      要在 SSIS 中使用此功能,您只需添加“执行 SQL”任务并将代码放入其中。

      【讨论】:

        【解决方案6】:

        我通常更喜欢让 SSIS 引擎来管理增量合并。只有新项目被插入并被更新。 如果您的目标服务器没有足够的资源来管理繁重的查询,则此方法允许使用您的 SSIS 服务器的资源。

        【讨论】:

          【解决方案7】:
          【解决方案8】:

          我会使用“缓慢变化的维度”任务

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-12-17
            • 1970-01-01
            • 1970-01-01
            相关资源
            最近更新 更多