2016-10-13 4 views
0

Я мог бы спуститься с неправильным путем. Однако, здесь. Я пытаюсь взять несколько листов excel и загрузить их в SQL Server с помощью SSIS.Столбец SSIS в нормализованном виде

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|...

Image of staging table to production table mapping

У меня есть попробовал 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 и использовать идентификатор для заполнения t2, t3 из промежуточной таблицы.

EDIT:Ниже приведено рабочее решение. Однако я не уверен, что это хорошее решение.

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 
+0

Что вам мешает назначая строку в ID в промежуточной таблице, а затем используя это для всех выборочных групп поселений? – iamdave

+0

В настоящее время 'IDENTITY_INSERT' выключен, поэтому я не могу явно предоставить PK для таблицы, содержащей таблицу t1. Я изучу, могу ли я включить это без каких-либо последствий для интерфейса. – txDMTN

+0

Я имею в виду, присвойте идентификатор в промежуточной таблице, используя данные из ваших целевых таблиц. Я написал ответ, который иллюстрирует это. Кроме того, ваш вопрос неясно, каковы идентификаторы на самом деле, так как у вас есть то же значение идентификатора, что и PK и FK в таблицах 2 и 3? – iamdave

ответ

0

Вы можете создать 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; 
Смежные вопросы