Sql server 如何在基于集合的语句中导入联接表?

Sql server 如何在基于集合的语句中导入联接表?,sql-server,sql-server-2008-r2,import,Sql Server,Sql Server 2008 R2,Import,我正在将数据从平面文件导入规范化的表结构。我目前正在使用游标插入到相关表中,因此我有主键插入到联接表中。我可以在SQL Server 2008 R2中以基于集合的方式执行此操作吗 我有3张桌子:联系人、电话和联系人电话。运行导入后,我希望联系人表中有2个联系人,电话表中有2个联系人,联系人电话表中有2个联系人。真正的导入要复杂得多,但如果能够实现这一点,我就可以将真正的导入从游标迁移到基于集合的解决方案 看起来merge或output关键字应该能够完成我想要的任务,但是我还不能让语法正常工作 下

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

我有3张桌子:联系人、电话和联系人电话。运行导入后,我希望联系人表中有2个联系人,电话表中有2个联系人,联系人电话表中有2个联系人。真正的导入要复杂得多,但如果能够实现这一点,我就可以将真正的导入从游标迁移到基于集合的解决方案

看起来merge或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

使用
contacts
Phones
上的
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  


您可以不合并就完成此操作。添加联系人和电话,然后创建与导入表匹配的联系人电话关系:

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;

迈克,这太完美了!我不理解0=1的语法,也永远不会明白这一点,所以我以后必须仔细阅读。再次感谢@DavidSilvaSmith-它确保合并中没有任何匹配项,因为您真正想要的是插入所有行。在我链接的问题中阅读更多关于它的信息。哦,我明白了。不是特殊语法,只是因为我们正在进行导入,所以从不匹配,0永远不会等于1。谢谢