2010-07-20 5 views
0

Je veux copier N nombre d'enregistrements dans une table qui est facile avec un INSERT SELECT mais après l'insertion je veux une liste montrant oldId et newId. Disons donc que j'ai une instruction SELECT qui retourne:Comment puis-je cloner des enregistrements dans une table et connaître les nouveaux et anciens ID?

ID | Name 
3 | Test A 
4 | Test B 
5 | Test C 

Si je fais un SELECT INTO de cela, il insère 3 nouvelles clés primaires. Je veux une liste montrant les nouveaux et anciens Ids par ex.

3 | 49 
4 | 50 
5 | 51 

Je sais comment faire avec des boucles, des curseurs, SCOPE_IDENTITY(), ou tables temporaires etc avec de nombreuses lignes de code, mais je me demandais s'il y a un moyen de couperet pour obtenir la nouvelle liste/vieux dans une ligne de SQL après INSERT SELECT par exemple

INSERT INTO tbl(Name) 
SELECT Name 
FROM tbl 
WHERE blah = 1 
. 
SELECT New_Old_Ids() 

Et je ne peux pas joindre à la table pour lui-même parce que « nom » est pas unique, donc je suis à la recherche d'une sorte de construit en fonction SQL. Ce n'est probablement pas possible mais j'ai pensé que je demanderais.

Je suis sur SQL Server 2005.

Vive Matthew

+0

Salut à tous. Il y a quelques bonnes idées. Je n'ai jamais entendu parler de OUTPUT alors je vais y jeter un coup d'œil. J'utilise la colonne oldId pour le moment mais j'espère qu'il existe un gourou SQL avec une solution d'une seule ligne? –

Répondre

1

Si vous êtes prêt à stocker la précédente PK dans le tableau, vous pouvez afficher les ID avec le OUTPUT clause:

DECLARE @t TABLE (
    PK INT NOT NULL IDENTITY(1,1), 
    Name VARCHAR(50), 
    PrevPK INT 
) 

INSERT @t (Name) 
SELECT 'A' UNION ALL SELECT 'B' UNION ALL SELECT 'C' UNION ALL 
SELECT 'D' UNION ALL SELECT 'E' 


INSERT @t (Name, PrevPK) 
OUTPUT Inserted.PK, Inserted.PrevPK 
SELECT Name, PK 
FROM @t t 
WHERE 0=0 

/** Results **/ 
PK   PrevPK 
----------- ----------- 
6   1 
7   2 
8   3 
9   4 
10   5 
+0

+1 Même réponse une minute plus vite :) – Andomar

2

Vous pouvez générer les nouveaux ID à l'aide de la clause output. Mais il ne peut pas afficher les colonnes que vous n'insérez pas, comme l'identifiant dans l'ancienne table.

Une façon de contourner c'est d'ajouter une colonne oldid à la table de destination:

declare @src table (id int identity, name varchar(50)) 
declare @dest table (id int identity, name varchar(50), oldid int) 

insert into @src (name) values ('John') 
insert into @src (name) values ('Jason') 
insert into @src (name) values ('Aasif') 
insert into @dest (name) values ('Larry') 

insert into @dest (name, oldid) 
output inserted.* 
select name, id from @src 

Bien sûr, au lieu de la clause output, vous pouvez maintenant:

select id, oldid 
from @dest 
+0

Excellente réponse ... – 8kb

Questions connexes