我是一个SSIS新手,虽然整个系统看起来很简单,但我从概念上并不了解在这种情况下我需要经历的过程:
需要将源数据库中的Invoice和InvoiceLine表映射到目标数据库中的两个等效表 - 具有不同的标识值。
对于插入的每张发票,我需要获取分配的身份,然后插入引用该新身份的所有行
发票上有一个代理键(发票号),但这些密钥也可能与目标系统中的发票号冲突,因此它们也必须重新编号。
这必须是集成中的常见场景 - 是否有共同的解决方案?
答案 0 :(得分:1)
如果您加载的数据很小(数百或数千但不是数百万),那么您可以这样做:使用OLEDB命令为每个父行执行一次插入并返回标识值;然后从那里将输出连接到子行,然后插入它们。优点:直观。缺点:规模严重。这种方法记录在网络上,谷歌应该为您提供。
如果我们谈论的是需要批量加载的更大系统,那么还有另外两种口味:
一个。如果您在加载期间对表有独占访问权(实际上是独占的,以某种方式强制执行),那么您可以从表中获取最大现有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任务以将其关闭,因为您一次只能在一个表上使用。