2011-12-27 5 views
6

Sto importando i dati da un file flat in una struttura di tabella normalizzata. Attualmente sto usando i cursori per fare inserimenti in tabelle correlate, quindi ho le chiavi primarie da inserire nella tabella di join. Posso farlo in un modo basato su set in SQL Server 2008 R2?Come posso importare in una tabella di join in un'istruzione basata su set?

Ho 3 tabelle: contatti, telefoni e contactphone. Dopo aver eseguito l'importazione mi piacerebbe che ci fossero 2 contatti nella tabella dei contatti, 2 nella tabella dei telefoni e 2 nella tabella dei contatti. La vera importazione è considerevolmente più complicata, ma far funzionare questo mi consentirà di migrare la vera importazione dai cursori a una soluzione basata su set.

Sembra che le parole chiave di unione o di output dovrebbero essere in grado di fare ciò che voglio ma non sono riuscito a far funzionare la sintassi.

Ecco un esempio di codice provandolo con OUTPUT. Ho quasi finito questo lavoro, ma non ho potuto importare 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 

Ecco un esempio di codice provarlo con unione:

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 

risposta

2

Usa merge su contacts e Phones e memorizzare l'output in una variabile di tabella da utilizzare quando si inserisce in 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, questo è perfetto! Non capisco la sintassi 0 = 1, e non l'avrei mai capito, quindi dovrò leggerlo più avanti. Grazie ancora! –

+0

@DavidSilvaSmith - Si assicura che non vi siano corrispondenze nell'unione perché ciò che realmente si desidera è inserire tutte le righe. Leggi di più a riguardo nella domanda che ho collegato. –

+1

Ohhhhhh ho capito. La sintassi non speciale, non corrisponde mai mai dato che stiamo eseguendo un'importazione e 0 non sarà mai uguale a 1. Grazie! –

0

Si potrebbe fare questo senza unione. Aggiungi i contatti e i telefoni, quindi crea le relazioni contatto-telefono corrispondenti alla tabella di importazione:

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; 
Problemi correlati