Hoe kopieer je een record in een SQL-tabel maar verwissel je de unieke id van de nieuwe rij?

Deze vraagkomt in de buurt van wat ik nodig heb, maar mijn scenario is iets anders. De brontabel en de bestemmingstabel zijn hetzelfde en de primaire sleutel is een uniqueidentifier (guid). Als ik dit probeer:

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

Ik krijg duidelijk een schending van de primaire sleutelbeperking, omdat ik probeer de primaire sleutel te kopiëren. Eigenlijk wil ik de primaire sleutel helemaal niet kopiëren. In plaats daarvan wil ik een nieuwe maken. Bovendien wil ik selectief bepaalde velden kopiëren en de andere null laten. Om de zaken ingewikkelder te maken, moet ik de primaire sleutel van het originele record nemen en deze in een ander veld in de kopie invoegen (veld PreviousId).

Ik weet zeker dat hier een gemakkelijke oplossing voor is, ik ken gewoon niet genoeg TSQL om te weten wat het is.


Antwoord 1, autoriteit 100%

Probeer dit:


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

Alle velden die niet zijn opgegeven, moeten hun standaardwaarde krijgen (die meestal NULL is als ze niet zijn gedefinieerd).


Antwoord 2, autoriteit 53%

Ok, ik weet dat het een oud probleem is, maar ik post toch mijn antwoord.

Ik vind deze oplossing goed. Ik hoef alleen de identiteitskolom(men) op te geven.

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;

De “id”-kolom is de identiteitskolom en dat is de enige kolom die ik moet specificeren. Het is sowieso beter dan andersom. 🙂

Ik gebruik SQL Server. Misschien wilt u “CREATE TABLE” en “UPDATE TABLE” in rij 1 en 2 gebruiken.
Hmm, ik zag dat ik niet echt het antwoord gaf dat hij wilde. Hij wilde de id ook naar een andere kolom kopiëren. Maar deze oplossing is leuk om een ​​kopie te maken met een nieuwe auto-id.

Ik bewerk mijn oplossing met de ideeën van 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;

Je kunt meer dan één kolom laten vallen door ze te scheiden met een “,”.
De :id moet worden vervangen door de id van de rij die u wilt kopiëren.
MyDatabase, MyTable en IndexField moeten (uiteraard) worden vervangen door uw namen.


Antwoord 3, autoriteit 8%

Ik vermoed dat je probeert te voorkomen dat je alle kolomnamen opschrijft. Als u SQL Management Studio gebruikt, kunt u eenvoudig met de rechtermuisknop op de tabel klikken en Script As Insert.. dan kunt u met die uitvoer rommelen om uw query te maken.


Antwoord 4, autoriteit 5%

Specificeer alle velden behalve uw ID-veld.

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

Antwoord 5, autoriteit 4%

Ik heb hetzelfde probleem waarbij ik wil dat een enkel script werkt met een tabel waaraan kolommen periodiek worden toegevoegd door andere ontwikkelaars. Niet alleen dat, maar ik ondersteun veel verschillende versies van onze database, aangezien klanten mogelijk niet allemaal up-to-date zijn met de huidige versie.

Ik heb de oplossing van Jonas genomen en enigszins aangepast. Hierdoor kan ik een kopie van de rij maken en vervolgens de primaire sleutel wijzigen voordat ik deze weer aan de oorspronkelijke brontabel toevoegt. Dit is ook erg handig voor het werken met tabellen die geen NULL-waarden in kolommen toestaan ​​en u niet elke kolomnaam in de INSERT wilt opgeven.

Deze code kopieert de rij voor ‘ABC’ naar ‘XYZ’

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

Zodra u klaar bent met het neerzetten van de tijdelijke tabel.

DROP TABLE #TempRow;

Antwoord 6, autoriteit 3%

Ik weet dat mijn antwoord te laat op het feest is. Maar de manier waarop ik het heb opgelost is iets anders dan alle antwoorden.

Ik had een situatie, ik moet een rij in een tabel klonen, behalve enkele kolommen. Die paar zullen nieuwe waarden hebben. Dit proces zou automatisch ondersteuning moeten bieden voor toekomstige wijzigingen in de tabel. Dit houdt in dat u het record moet klonen zonder kolomnamen op te geven.

Mijn benadering is om,

  1. Query Sys.Columns om de volledige lijst met kolommen voor de tabel te krijgen en de namen op te nemen
    aantal kolommen om over te slaan in de where-clausule.
  2. Converteer dat naar CSV als kolomnamen.
  3. Build Select … Op basis hiervan invoegen in script.

declare @columnsToCopyValues varchar(max), @query varchar(max)
SET @columnsToCopyValues = ''
--Get all the columns execpt Identity columns and Other columns to be excluded. Say IndentityColumn, Column1, Column2
Select @columnsToCopyValues = @columnsToCopyValues  + [name] + ', ' from sys.columns c where c.object_id = OBJECT_ID('YourTableName') and name not in ('IndentityColumn','Column1','Column2')
Select @columnsToCopyValues = SUBSTRING(@columnsToCopyValues, 0, LEN(@columnsToCopyValues))
print @columnsToCopyValues
Select @query = CONCAT('insert into YourTableName (',@columnsToCopyValues,', Column1, Column2) select ', @columnsToCopyValues, ',''Value1'',''Value2'',', ' from YourTableName where IndentityColumn =''' , @searchVariable,'''')
print @query
exec (@query)


Antwoord 7

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

Antwoord 8

Als “sleutel” uw PK-veld is en het is autonumeriek.

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

het genereert een nieuw record, waarbij veld1 en veld2 uit het originele record worden gekopieerd


Antwoord 9

Mijn tabel heeft 100 velden en ik had een query nodig om gewoon te werken. Nu kan ik een willekeurig aantal velden uitschakelen met wat elementaire voorwaardelijke logica en me geen zorgen maken over de ordinale positie.

  1. Vervang de onderstaande tabelnaam door uw tabelnaam

    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. Vervang de oorspronkelijke identiteitsveldnaam door uw PK-veldnaam

    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. Vervang de tabelnamen opnieuw (zowel de naam van de doeltabel als de naam van de brontabel); bewerk uw wherevoorwaarden

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

Antwoord 10

Je kunt het als volgt doen:

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

Daar in plaats van 112 moet je een nummer van het maximale id in tabel DENI/FRIEN01P zetten.


Antwoord 11

Hier is hoe ik het deed met ASP classic en ik kreeg het niet helemaal werkend met de bovenstaande antwoorden en ik wilde een product in ons systeem kunnen kopiëren naar een nieuw product_id en had het nodig om te kunnen werken zelfs als we meer kolommen aan de tabel toevoegen.

Cn.Execute("CREATE TEMPORARY TABLE temprow AS SELECT * FROM product WHERE product_id = '12345'")
Cn.Execute("UPDATE temprow SET product_id = '34567'")
Cn.Execute("INSERT INTO product SELECT * FROM temprow")
Cn.Execute("DELETE temprow")
Cn.Execute("DROP TABLE temprow")

Other episodes