【问题标题】:Integration services and identity columns集成服务和身份列
【发布时间】:2009-07-15 00:39:34
【问题描述】:

我是一个 SSIS 新手,虽然整个系统看起来很简单,但我从概念上不理解在这种情况下我需要经历的过程:

  1. 需要将 Invoice 和 InvoiceLine 表从源数据库映射到目标数据库中的两个等效表 - 具有不同的标识值。

  2. 对于插入的每张发票,我需要获取分配给它的身份,然后插入引用该新身份的所有行

  3. 发票上有一个代理键(发票号),但它们也可能与目标系统中的发票号冲突,因此也必须重新编号。

这一定是集成中的常见场景——有没有通用的解决方案?

【问题讨论】:

    标签: sql-server ssis


    【解决方案1】:

    Chris KL - 你说得对,这比人们想象的要难。为此,我有三种方法,它们适用于不同的情况:

    1. 如果您正在加载的数据很小(数百或数千但不是数十万),那么您可以这样做:使用 OLEDB 命令为每个父行执行一次插入并返回标识值;然后从该下游连接该输出到子行,并插入它们。优点:直观。缺点:扩展性很差。此方法已在网络上记录,您应该使用 Google 进行搜索。

    2. 如果我们谈论的是需要批量加载的更大系统,那么还有另外两种风格:

    一个。如果您在加载期间对表具有独占访问权限(确实是独占,以某种方式强制执行),那么您可以从表中获取最大现有 ID,使用 SSIS 脚本任务对从该最大 ID 以上开始的行进行编号,然后设置身份插入打开,将它们塞进去,然后设置身份插入关闭。然后,您可以在 SSIS 中将这些脚本生成的键分配给子行。优点:快速简单,一趟DB。缺点:如果其他一些进程同时插入到您的表中,可能会出错。易碎。

    b.如果您没有独占访问权限,那么我所知道的唯一方法是往返数据库,因此:插入所有父行,但跟踪它们的不是身份列的键(业务键,例如)。在第二个数据流中,使用查找转换处理子记录,该转换使用业务键来获取父 ID。确保查找与缓存进行了适当调整,并且您的业务密钥已编入索引。

    【讨论】:

      【解决方案2】:

      好的,恐怕这是一个好消息/坏消息的情况。首先是好消息和一些你可能知道的背景知识,但如果你不知道,我会记下来。

      您一般不能将任何东西插入到 IDENTITY 列中。当然,就像生活中的其他事情一样,有时您需要这样做,而这可以通过 IDENTITY_INSERT 选项来完成。

      SET IDENTITY_INSERT MyTable ON
      
      INSERT INTO MyTable (
             MyIdCol,
             Etc…
             ) 
      SELECT SourceIdCol,
             Etc…
        FROM MySourceTable
      
          SET IDENTITY_INSERT MyTable OFF
      

      现在,您说您在目标中有代理键,但您说它们可能会发生冲突。所以我有点困惑……您是在使用源中的键(例如 IDENTITY 列)还是在目标中生成新键?我强烈建议不要尝试将键空间合并到单个键列中。如果您需要保留键,那么我建议使用类似 SourceSystemId 的多字段键来保持它们的唯一性。

      最后一个坏消息:SSIS 没有提供使用 IDENTITY_INSERT 选项的简单方法。我能够做到这一点的唯一方法是在插入任务之前执行的 SQL 任务中打开它。您应该能够将表名作为变量传递到脚本中。确保在之后包含另一个 SQL 任务以将其关闭,因为您一次只能在一个表上使用。

      【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-17
      • 1970-01-01
      • 1970-01-01
      • 2014-05-25
      • 2013-02-22
      相关资源
      最近更新 更多