2017-08-30 2 views
1

La base de données est SQL Server 2012.Obtenir l'ID séquencée d'une ligne à la clé étrangère d'une ligne dans une autre table dans une requête

Je suis censé ajouter un tas de lignes sur deux tables à partir d'un Fichier Excel.

J'ai la table Customers:

id | firstname | lastname 
1 | John  | Doe 
etc. 

Le tableau Customers a une séquence customers_seq à utiliser pour ids pour de nouvelles lignes. Parce qu'au moment de l'insertion, la quantité de lignes n'est pas connue. Comme suit:

insert into Customers (id,firstname,lastname) 
    values 
    (next value for customers_seq, '2016-001', 'John', 'Doe'), 
    (next value for customers_seq, '2016-002', 'Jane', 'Doe'), 
    (next value for customers_seq, '2016-003', 'Steve', 'Waters'); 
-- tons of more customers -- 

Cela fonctionne comme prévu.

J'ai aussi la table Services

id | name | fk_Customers 
1 | lunch| 2 
etc. 

Maintenant, voici le problème:

Je suis censé - dans cette même requête où j'ajouter le Customers rows- pour ajouter une ligne sur la table Services après chaque ligne ajoutée à la table Customers afin que la séquence id générée par séquence pour la ligne Customers devienne la valeur de la colonne fk_Customers sur la ligne qui est ajoutée à le tableau Services.

Je pensais que cela pourrait être possible en utilisant les variables TSQL Local.

Donc, quelque chose comme:

DECLARE @sequenceCreatedId bigint; 
SET @sequenceCreatedId = next value for customers_seq; 

insert into Customers (id,firstname,lastname) 
values(@sequenceCreatedId, '2016-001', 'John', 'Doe') 

insert into Services (id,name,fk_Customers) 
values(next value for services_seq, someName, @sequenceCreatedId); 

--And just repeat that whole thing. Setting that variable again and again-- 

SET @sequenceCreatedId = next value for customers_seq; 

insert into Customers (id,firstname,lastname) 
values(@sequenceCreatedId, '2016-002', 'Jane', 'Doe') 

insert into Services (id,name,fk_Customers) 
values(next value for services_seq, anotherName, @sequenceCreatedId); 

Y at-il une meilleure façon de le faire?

Répondre

1

Bien sûr, utiliser la partie inserted du output clause pour obtenir tous à la fois:

declare @customers table (
    id int not null identity(0, 1) 
    , firstname nvarchar(100) not null 
    , lastname nvarchar(100) not null 
); 

insert into @customers (firstname, lastname) 
output inserted.* 
values ('John', 'Doe') 
    , ('Jane', 'Doe') 
    , ('Steve', 'Waters'); 

Mon exemple n'utilise pas de séquence, mais ça va marcher de la même façon. Notez que cela fonctionnera également pour un update ou delete; on peut même obtenir les anciennes et nouvelles valeurs en une seule fois en utilisant à la fois deleted et inserted:

update a 
    set a.FirstName = Convert(nvarchar(100), NewId()) 
output deleted.FirstName as OldFirstName 
    , inserted.FirstName as NewFirstName 
from @customers as a;