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

Cette question se rapproche de ce dont j'ai besoin, mais mon scénario est légèrement différent. La table source et la table de destination sont identiques et la key primaire est un identificateur unique (guid). Quand j'essaye ceci:

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

J'obtiens évidemment une violation de contrainte de key primaire, puisque j'essaie de copyr sur la key primaire. En fait, je ne veux pas du tout copyr sur la key primaire. Au contraire, je veux en créer un nouveau. De plus, j'aimerais copyr sélectivement certains champs et laisser les autres vides. Pour rendre les choses plus complexes, je dois prendre la key primaire de l'logging original et l'insert dans un autre champ de la copy (champ PreviousId).

Je suis sûr qu'il y a une solution facile à cela, je ne connais pas assez TSQL pour savoir de quoi il s'agit.

Essaye ç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 si elle n'est pas définie).

Ok, je sais que c'est un vieux problème mais je post ma réponse quand même.

J'aime cette solution. Je n'ai qu'à 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; 

Le "id" -column est la colonne d'identité et c'est la seule colonne que je dois spécifier. C'est mieux que l'inverse de toute façon. 🙂

J'utilise SQL Server. Vous pouvez utiliser " CREATE TABLE " et " UPDATE TABLE " aux lignes 1 et 2. Hmm, j'ai vu que je n'ai pas vraiment donné la réponse qu'il voulait. Il voulait également copyr l'identifiant dans une autre colonne. Mais cette solution est sympa pour faire une copy avec un nouvel identifiant automatique.

J'édite ma solution avec les idéas 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 supprimer plusieurs colonnes en les séparant par un ",". L'identifiant: doit être remplacé par l'identifiant de la ligne que vous voulez copyr. MyDatabase, MyTable et IndexField devraient être remplacés par vos noms (bien sûr).

Indiquez tous les champs sauf votre champ d'ID.

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

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

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

Si "key" est votre champ PK et qu'il est autonumérique.

 insert into MyTable (field1, field2, field3, parentkey) select field1, field2, null, key from MyTable where uniqueId = @Id 

il va générer un nouvel logging, en copiant field1 et field2 à partir de l'logging d'origine

Vous pouvez faire comme ceci:

 INSERT INTO DENI/FRIEN01P SELECT RCRDID+112, PROFESION, NAME, SURNAME, AGE, RCRDTYP, RCRDLCU, RCRDLCT, RCRDLCD FROM FRIEN01P 

Là, au lieu de 112, vous devriez mettre un nombre de maximum id dans la table DENI / FRIEN01P.

Ma table a 100 champs, et j'avais besoin d'une requête pour fonctionner. Maintenant, je peux changer n'importe quel nombre de champs avec une logique conditionnelle de base et ne pas m'inquiéter de sa position ordinale.

  1. Remplacez le nom de la table ci-dessous par le nom de votre table

     SQLcolums = "SELECT COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE (TABLE_NAME = 'TABLE-NAME')" Set GetColumns = Conn.Execute(SQLcolums) Do WHILE not GetColumns.eof colName = GetColumns("COLUMN_NAME") 
  2. Remplacez le nom du champ d'identité d'origine par votre nom de champ PK

     IF colName = "ORIGINAL-IDENTITY-FIELD-NAME" THEN ' ASSUMING THAT YOUR PRIMARY KEY IS THE FIRST FIELD DONT WORRY ABOUT COMMAS AND SPACES columnListSOURCE = colName columnListTARGET = "[PreviousId field name]" ELSE columnListSOURCE = columnListSOURCE & colName columnListTARGET = columnListTARGET & colName END IF GetColumns.movenext loop GetColumns.close 
  3. Remplacez les noms de table à nouveau (à la fois le nom de la table cible et le nom de la table source); éditez vos conditions d' where

     SQL = "INSERT INTO TARGET-TABLE-NAME (" & columnListTARGET & ") SELECT " & columnListSOURCE & " FROM SOURCE-TABLE-NAME WHERE (FIELDNAME = FIELDVALUE)" Conn.Execute(SQL) 

J'ai le même problème où je veux qu'un seul script fonctionne avec une table qui a des colonnes ajoutées périodiquement par d'autres développeurs. Non seulement cela, mais je suis en charge de nombreuses versions différentes de notre database, car les clients peuvent ne pas tous être à jour avec la version actuelle.

J'ai pris la solution par Jonas et l'ai légèrement modifiée. Cela me permet de faire une copy de la ligne, puis de modifier la key primaire avant de la réintégrer dans la table source d'origine. C'est aussi très pratique pour travailler avec des tables qui n'autorisent pas les valeurs NULL dans les colonnes et vous ne voulez pas avoir à spécifier chaque nom de colonne dans l'INSERT.

Ce code copy la ligne pour 'ABC' à 'XYZ'

 SELECT * INTO #TempRow FROM SourceTable WHERE KeyColumn = 'ABC'; UPDATE #TempRow SET KeyColumn = 'XYZ'; INSERT INTO SourceTable SELECT * FROM #TempRow; DELETE #TempRow; 

Une fois que vous avez terminé, déposez la table temporaire.

 DROP TABLE #TempRow;