142 votes

Comment copier un enregistrement dans une table SQL mais échanger l'identifiant unique de la nouvelle ligne ?

Cette question est proche de ce dont j'ai besoin, mais mon scénario est légèrement différent. La table source et la table destination sont les mêmes et la clé primaire est un identifiant unique (guid). Lorsque j'essaie ceci :

insert into MyTable
    select * from MyTable where uniqueId = @Id;

J'obtiens évidemment une violation de contrainte de clé primaire, puisque je tente de copier la clé primaire. En fait, je ne veux pas du tout copier la clé primaire. Je veux plutôt en créer une nouvelle. De plus, je voudrais copier sélectivement certains champs et laisser les autres nuls. Pour rendre les choses plus complexes, je dois prendre la clé primaire de l'enregistrement original et l'insérer dans un autre champ de la copie (champ PreviousId).

Je suis sûr qu'il existe une solution simple à ce problème, mais je ne connais pas suffisamment le langage TSQL pour la connaître.

208voto

AaronSieb Points 4598

Essayez ça :

insert into MyTable(field1, field2, id_backup)
    select field1, field2, uniqueId from MyTable where uniqueId = @Id;

Tous les champs non spécifiés doivent recevoir leur valeur par défaut (qui est généralement NULL lorsqu'elle n'est pas définie).

2 votes

Génial. Ça a marché comme un charme. C'était tellement évident une fois que tu l'as écrit. Merci !

2 votes

Cela fonctionnera si vous avez peu de colonnes. Si vous avez disons 20 ou 30 colonnes, vous pouvez toujours utiliser cette méthode, mais ce serait décourageant. En outre, chaque fois que vous ajoutez une colonne et que vous voulez copier ces données aussi, vous devez ajouter la colonne à ce script. Le mieux est de générer l'insertion dynamiquement en utilisant les tables sys.

113voto

Jonas Points 120

Ok, je sais que c'est une vieille question mais je poste quand même ma réponse.

J'aime cette solution. Je dois seulement spécifier la ou les colonnes d'identité.

SELECT * INTO TempTable FROM MyTable_T WHERE id = 1;
ALTER TABLE TempTable DROP COLUMN id;
INSERT INTO MyTable_T SELECT * FROM TempTable;
DROP TABLE TempTable;

La colonne "id" est la colonne d'identité et c'est la seule colonne que je dois spécifier. De toute façon, c'est mieux que l'inverse :-)

J'utilise SQL Server. Vous pouvez utiliser " CREATE TABLE " et " UPDATE TABLE "à la ligne 1 et 2. Hmm, j'ai vu que je n'ai pas vraiment donné la réponse qu'il voulait. Il voulait aussi copier l'id dans une autre colonne. Mais cette solution est intéressante pour faire une copie avec un nouvel auto-id.

Je modifie ma solution avec les idées de Michael Dibbets.

use MyDatabase; 
SELECT * INTO #TempTable FROM [MyTable] WHERE [IndexField] = :id;
ALTER TABLE #TempTable DROP COLUMN [IndexField]; 
INSERT INTO [MyTable] SELECT * FROM #TempTable; 
DROP TABLE #TempTable;

Vous pouvez déposer plus d'une colonne en les séparant par un ",". Le :id doit être remplacé par l'identifiant de la ligne que vous souhaitez copier. MyDatabase, MyTable et IndexField doivent être remplacés par vos noms (bien sûr).

1 votes

C'est délicat, comment pouvez-vous être sûr que vous copiez le bon identifiant à la bonne ligne pendant l'INSERT INTO de la ligne 3 ?

0 votes

La colonne id est une colonne d'identité (dans ma table), donc je ne me soucie pas de la valeur. Je veux simplement un nouvel enregistrement contenant les mêmes valeurs que l'"ancien".

0 votes

Id = 1 sur la première ligne est juste un exemple.

18voto

Matt Hinze Points 9686

Je suppose que vous essayez d'éviter d'écrire tous les noms de colonnes. Si vous utilisez SQL Management Studio, vous pouvez facilement faire un clic droit sur la table et script As Insert puis vous pouvez vous amuser avec cette sortie pour créer votre requête.

0 votes

J'adore cette approche, cette astuce est simple mais fonctionne comme un charme.

10voto

Scott Bevington Points 1111

Spécifiez tous les champs sauf le champ ID.

INSERT INTO MyTable (FIELD2, FIELD3, ..., FIELD529, PreviousId)
SELECT FIELD2, NULL, ..., FIELD529, FIELD1
FROM MyTable
WHERE FIELD1 = @Id;

2voto

Jeffrey L Whitledge Points 27574
insert into MyTable (uniqueId, column1, column2, referencedUniqueId)
select NewGuid(), // don't know this syntax, sorry
  column1,
  column2,
  uniqueId,
from MyTable where uniqueId = @Id

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X