【问题标题】:SSIS Staging Table to Normalized formSSIS 临时表到规范化形式
【发布时间】:2016-10-13 16:05:30
【问题描述】:

我可能会走错路。但是,这里有。我正在尝试获取多个 excel 工作表并使用 SSIS 将它们加载到 SQL Server 中。

Excel表格:

RQ|Descr|PartNum|Manufacturer|...

我正在将它加载到一个包含几个派生列的临时表中:

RQ|Descr|PartNum|Manufacturer|Origin|DateTime|...

这没什么大不了的,我可以轻松做到这一点。但是,问题是如何将数据从暂存表获取到正确的表并确保遵循 FK 约束。请参阅下面的插图。

我的目标是采取RQ|Descr|PartNum|Manufacturer|Origin|DateTime|... 并填充多个表

[t1]id|RQ|Descr|Origin|DateTime

[t2]id|t1_id|PartNum|Manufacturer

[t3]id|t1_id|...

我已经尝试过MERGE,但是我不确定如何保持 FK 关系。

MERGE INTO spin_item AS targ

USING ssis_stage AS src ON 1=0 -- always generates "not matched by target"

WHEN NOT MATCHED BY TARGET THEN
    -- INSERT into spin_item:
    INSERT (description, reqqty, price, origin, datetime, exclude, status, siteid, production, repairable)      
    VALUES (src.description, src.rq, src.price, src.origin, GETDATE(), 0, 'N', '', 0, 0)

    -- INSERT into spin_part: 
    OUTPUT inserted.ID, src.manufacturer, src.partnum 
    INTO spin_part (ID, src.manufacturer, src.partnum);

我已经研究了这个SSIS : Using multicast to enter data into 2 RELATED destinations,但这是一个一对多的关系。所以,我不确定如何填充我的 t1 表并使用 id 从临时表中填充 t2、t3。

编辑: 下面,似乎是一个可行的解决方案。但是,我不确定这是一个好的解决方案。

BEGIN
SET IDENTITY_INSERT dbo.spin_item ON

--Insert into spin_item
MERGE INTO spin_item AS targ
USING ssis_stage AS src ON 1=0

WHEN NOT MATCHED BY TARGET THEN
    INSERT (id, description, reqqty, price, origin, datetime, exclude, status, siteid, production, repairable)
    VALUES (src.id, src.description, src.rq, src.price, src.origin, GETDATE(), 0, 'N', '', 0, 0);
SET IDENTITY_INSERT dbo.spin_item OFF

--Insert into spin_part
MERGE INTO spin_part AS targ
USING ssis_stage AS src ON 1=0

WHEN NOT MATCHED BY TARGET AND src.partnum IS NOT NULL THEN
    INSERT (itemid_id, manufacturer, partnum, catalognum, [primary])
    VALUES (src.id, src.manufacturer, src.partnum, src.partnum, 1);

--Insert into spin_stock
MERGE INTO spin_stock AS targ
USING ssis_stage AS src ON 1=0

WHEN NOT MATCHED BY TARGET AND src.stock IS NOT NULL THEN
    INSERT (itemid_id, stocknum)
    VALUES (src.id, src.stock);  


--Insert into spin_collaboration        
MERGE INTO spin_collaboration AS targ
USING ssis_stage AS src ON 1=0

WHEN NOT MATCHED BY TARGET AND src.notes IS NOT NULL THEN
    INSERT (itemid_id, comment, datetime)
    VALUES (src.id, src.notes, GETDATE());

DELETE FROM ssis_stage WHERE id > 0 --Instead of Truncate since auto_increment will reset.

END

【问题讨论】:

  • 是什么阻止您在临时表中为行分配 ID,然后将其用于所有选择性表总体?
  • 目前,IDENTITY_INSERT 已关闭,因此我无法为 t1 的表填充显式提供 PK。我将探索是否可以在不影响前端的情况下打开它。
  • 我的意思是,使用目标表中的数据在临时表中分配 ID。我发布了一个答案来说明这一点。此外,您的问题不清楚 ID 的实际含义是什么,因为您在表 2 和表 3 中的 ID 值似乎与 PK 和 FK 相同?

标签: sql sql-server ssis


【解决方案1】:

您可以根据您的目标表在临时表上创建一个ID 列,然后将其用作每个表插入中的 FK:

declare @source table (ID int, a int, b int, c int);
insert into @source values
 (null,1,1,1)
,(null,1,1,2)
,(null,1,2,2)
,(null,5,3,2)
,(null,7,1,2)
,(null,2,1,2)

declare @target1 table (ID int, a int);
insert into @target1 values
 (1,5)
,(2,6)
,(3,99);

declare @target2 table (ID int, b int, c int);
insert into @target2 values
 (1,3,2)
,(2,9,7)
,(3,57,3);

update s
set ID = ss.IDNew
from @source s
    inner join (
                select row_number() over (order by a,b,c) + (select max(ID) from @target1) as IDNew
                        ,a
                        ,b
                        ,c
                from @source
                ) ss
        on(s.a = ss.a
            and s.b = ss.b
            and s.c = ss.c
            );

select * from @target1;
select * from @source;

insert into @target1
select ID
        ,a
from @source;

insert into @target2
select ID
        ,b
        ,c
from @source;

select * from @target1;
select * from @target2;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-07-17
    • 2021-12-24
    • 2011-03-08
    • 1970-01-01
    • 2022-01-11
    • 1970-01-01
    相关资源
    最近更新 更多