集成服务和标识列

时间:2009-07-15 00:39:35

标签: sql-server ssis

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

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

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

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

  4. 这必须是集成中的常见场景 - 是否有共同的解决方案?

2 个答案:

答案 0 :(得分:1)

克里斯·吉隆坡 - 你说的这比你想象的要难得多。我有三种方法,适用于不同的情况:

  1. 如果您加载的数据很小(数百或数千但不是数百万),那么您可以这样做:使用OLEDB命令为每个父行执行一次插入并返回标识值;然后从那里将输出连接到子行,然后插入它们。优点:直观。缺点:规模严重。这种方法记录在网络上,谷歌应该为您提供。

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

  3. 一个。如果您在加载期间对表有独占访问权(实际上是独占的,以某种方式强制执行),那么您可以从表中获取最大现有ID,使用SSIS脚本任务对从最大id开始的行进行编号,然后设置标识插入,填充它们,然后设置标识插入关闭。然后,您可以在SSIS中将这些脚本生成的密钥分配给子行。优点:快速简单,一次到DB。缺点:如果某些其他进程同时插入到您的表中,则可能出现错误。脆。

    湾如果您没有独占访问权限,那么我所知道的唯一方法是往返数据库,因此:插入所有父行,但跟踪不是标识列的密钥(业务密钥,例如)。在第二个数据流中,使用查找转换处理子记录,该转换使用业务键来获取父ID。确保查找与缓存相对应,并对该业务密钥编制索引。

答案 1 :(得分:0)

好吧,这是一个好消息/坏消息,我害怕。首先是你可能知道的好消息和一些背景,但是如果不这样做,我会把它放下来。

通常无法将任何插入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任务以将其关闭,因为您一次只能在一个表上使用。