2011-12-27 47 views
6

我正在将数据从平面文件导入标准化表结构。我目前使用游标做插入到相关的表,所以我有主键插入连接表。我可以在SQL Server 2008 R2中以基于集合的方式执行此操作吗?如何导入基于集合的声明中的连接表?

我有3个表格:联系人,电话和联系人电话。运行导入后,我希望在联系人表中有2个联系人,电话号码表中有2个联系人,contactPhones表中有2个联系人。真正的导入要复杂得多,但让它起作用会让我将真正的导入从游标移植到基于集合的解决方案。

似乎合并或输出关键字应该能够做我想做的事,但我一直没有能够使语法工作。

这是一个代码示例,用OUTPUT进行尝试。我得到这个几乎工作,除了我不能引用import.contactId。

create table import(contactId int identity, phone varchar(50), name varchar(10)) 
create table contacts (contactId int identity, name varchar(50)) 
create table contactPhone (contactId int, phoneId int) 
create table Phones (phoneId int identity, number varchar(10)) 

go 
insert into import (phone, name) 
    select '1872', 'dave' 
    union (select '9110', 'Jordan') 

insert into contacts 
    select name from import 
insert into Phones (number) 
    OUTPUT import.contactId, INSERTED.phoneId into contactPhone 
    select phone from import 

select * from contactPhone 

这里是合并尝试它一个代码示例:

create table import(contactId int identity, phone varchar(50), name varchar(10)) 
create table contacts (contactId int identity, name varchar(50)) 
create table contactPhone (contactId int, phoneId int) 
create table Phones (phoneId int identity, number varchar(10)) 

go 
insert into import (phone, name) 
    select '1872', 'dave' 
    union (select '9110', 'Jordan') 

insert into contacts 
    select name from import 

MERGE phones target 
    USING (select import.contactId, import.phone, import.name 
      from import join contacts on import.contactId = contacts.contactId) as source 
    ON (target.contactId = source.contactId) 
    WHEN MATCHED THEN 
     insert into Phones (number) 
      OUTPUT import.contactId, INSERTED.phoneId into contactPhone 
      select phone from import 
    WHEN NOT MATCHED THEN 
     INSERT (name) 
     VALUES (source.Name) 
     OUTPUT INSERTED.*; 



select * from contactPhone 

回答

2

contactsPhones使用merge并存储在表变量输出,当你插入contactPhone使用。

insert into import (phone, name) 
select '1872', 'dave' union all 
select '9110', 'Jordan' 

declare @ContactIDs table(SourceID int primary key, TargetID int) 
declare @PhoneIDs table (SourceID int primary key, TargetID int) 

merge contacts as c 
using import as i 
on 0 = 1 
when not matched then 
    insert (name) values (i.name) 
output i.contactId, inserted.contactId into @ContactIDs; 

merge Phones as p 
using import as i 
on 0 = 1 
when not matched then 
    insert (number) values (i.phone) 
output i.contactId, inserted.phoneId into @PhoneIDs; 

insert into contactPhone(contactId, phoneId) 
select c.TargetID, p.TargetID 
from import as i 
    inner join @ContactIDs as c 
    on i.contactID = c.SourceID 
    inner join @PhoneIDs as p 
    on i.contactID = p.SourceID 

Using merge..output to get mapping between source.id and target.id

http://data.stackexchange.com/stackoverflow/qt/122662/

+0

Mike,这很完美!我不明白0 = 1的语法,并且从来没有想到这一点,所以我将不得不在稍后阅读。再次感谢! – 2011-12-27 15:00:26

+0

@DavidSilvaSmith - 它确保在合并中没有任何匹配,因为您真正想要的是插入所有行。在我链接的问题中阅读更多关于它的内容。 – 2011-12-27 15:02:04

+1

Ohhhhhh我陷入了困境。没有特殊的语法,只是从来没有匹配,因为我们正在进行导入,而0将永远不会等于1.谢谢! – 2011-12-27 15:07:03

0

你可以做到这一点没有合并。添加联系人和电话,然后创建匹配导入表的联系电话关系:

insert into contacts 
    select name from import; 

insert into Phones 
    select phone from import; 

insert into contactPhone 
    select i.contactId 
    ,  p.phoneId 
    from import i 
    join phones p 
    on  p.number = i.phone 
    join contacts c 
    on  c.name = i.name;