2011-12-27 17 views
6

Importación de datos desde un archivo plano a una estructura de tabla normalizada. Actualmente estoy usando cursores para hacer inserciones en tablas relacionadas, así que tengo las claves principales para insertar en la tabla de unión. ¿Puedo hacer esto de una manera establecida en SQL Server 2008 R2?¿Cómo puedo importar a una tabla de unión en una declaración basada en conjunto?

Tengo 3 tablas: contactos, teléfonos y teléfonos de contacto. Después de ejecutar la importación, me gustaría que hubiera 2 contactos en la tabla de contactos, 2 en la tabla de teléfonos y 2 en la tabla de teléfonos de contacto. La importación real es considerablemente más complicada, pero hacer que esto funcione me permitirá migrar la importación real de los cursores a una solución basada en conjuntos.

Parece que las palabras clave de combinación o de salida deberían poder hacer lo que quiero, pero no he podido obtener la sintaxis para que funcione.

Aquí hay un ejemplo de código probándolo con OUTPUT. Conseguí que esto casi funcione, excepto que no pude hacer referencia a 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 

Aquí es un ejemplo de código de intentarlo con fusión:

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 

Respuesta

2

Uso merge en contacts y Phones y almacenar el resultado en una variable de tabla que se utilizará cuando se inserta en 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, esto es perfecto! No entiendo la sintaxis 0 = 1, y nunca lo habría averiguado, así que tendré que leer sobre eso más tarde. ¡Gracias de nuevo! –

+0

@DavidSilvaSmith - Se asegura de que no tenga ninguna coincidencia en la combinación, porque lo que realmente desea es insertar todas las filas. Lea más sobre esto en la pregunta que ligé. –

+1

Ohhhhhh tengo. No es una sintaxis especial, simplemente nunca coincida ya que estamos haciendo una importación, y 0 nunca será igual a 1. ¡Gracias! –

0

que podría hacer esto sin fusión. Agregue los contactos y teléfonos, y luego cree las relaciones de contacto telefónico que coincidan con la tabla de importación:

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; 
Cuestiones relacionadas