Diese Frage kommt nahe an das, was ich brauche, aber mein Szenario ist etwas anders. Die Quelltabelle und die Zieltabelle sind identisch und der Primärschlüssel ist ein eindeutiger Bezeichner (GUID). Wenn ich das versuche:
insert into MyTable
select * from MyTable where uniqueId = @Id;
Ich bekomme offensichtlich eine Verletzung der Primärschlüsselbeschränkung, da ich versuche, den Primärschlüssel zu kopieren. Eigentlich möchte ich den Primärschlüssel überhaupt nicht kopieren. Ich möchte vielmehr eine neue erstellen. Außerdem möchte ich bestimmte Felder selektiv kopieren und die anderen Felder leer lassen. Um die Angelegenheit komplexer zu gestalten, muss ich den Primärschlüssel des ursprünglichen Datensatzes nehmen und ihn in ein anderes Feld der Kopie einfügen (PreviousId-Feld).
Ich bin sicher, dass es eine einfache Lösung dafür gibt, ich weiß einfach nicht genug TSQL, um zu wissen, was es ist.
Versuche dies:
insert into MyTable(field1, field2, id_backup)
select field1, field2, uniqueId from MyTable where uniqueId = @Id;
Alle nicht angegebenen Felder sollten ihren Standardwert erhalten (normalerweise NULL, wenn sie nicht definiert sind).
Ok, ich weiß, dass es eine alte Frage ist, aber ich poste meine Antwort trotzdem.
Ich mag diese Lösung. Ich muss nur die Identitätsspalte (n) angeben.
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;
Die "id" -Spalte ist die Identitätsspalte und dies ist die einzige Spalte, die ich angeben muss. Es ist sowieso besser als umgekehrt. :-)
Ich benutze SQL Server. Sie können "CREATE TABLE
" und "UPDATE TABLE
" in Zeile 1 und 2 verwenden. Hmm, ich habe gesehen, dass ich nicht wirklich die Antwort gab, die er wollte. Er wollte die ID auch in eine andere Spalte kopieren. Diese Lösung ist jedoch nett, wenn Sie eine Kopie mit einer neuen Auto-ID erstellen.
Ich bearbeite meine Lösung mit den Ideen von 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;
Sie können mehr als eine Spalte löschen, indem Sie sie durch ein "," ..__ trennen. Die: ID sollte durch die ID der Zeile ersetzt werden, die Sie kopieren möchten . MyDatabase, MyTable und IndexField sollten durch Ihre Namen ersetzt werden (Na sicher).
Geben Sie alle Felder außer Ihrem ID-Feld an.
INSERT INTO MyTable (FIELD2, FIELD3, ..., FIELD529, PreviousId)
SELECT FIELD2, NULL, ..., FIELD529, FIELD1
FROM MyTable
WHERE FIELD1 = @Id;
Ich vermute, Sie versuchen zu vermeiden, alle Spaltennamen aufzuschreiben. Wenn Sie SQL Management Studio verwenden, können Sie einfach mit der rechten Maustaste auf die Tabelle und auf Skript als Einfügen klicken. Dann können Sie mit dieser Ausgabe herumspielen, um Ihre Abfrage zu erstellen.
insert into MyTable (uniqueId, column1, column2, referencedUniqueId)
select NewGuid(), // don't know this syntax, sorry
column1,
column2,
uniqueId,
from MyTable where uniqueId = @Id
Wenn "key" Ihr PK-Feld ist und es automatisch ist.
insert into MyTable (field1, field2, field3, parentkey)
select field1, field2, null, key from MyTable where uniqueId = @Id
es wird ein neuer Datensatz erstellt, wobei Feld1 und Feld2 aus dem ursprünglichen Datensatz kopiert werden
Ich weiß, dass meine Antwort zu spät zur Party kommt. Aber die Art, wie ich sie gelöst habe, ist etwas anders als alle Antworten.
Ich hatte eine Situation, ich muss eine Zeile in einer Tabelle außer einigen Spalten klonen. Diese wenigen werden neue Werte haben. Dieser Prozess sollte automatisch für zukünftige Änderungen an der Tabelle unterstützen. Dies bedeutet, dass Sie den Datensatz klonen, ohne Spaltennamen anzugeben.
Mein Ansatz ist zu
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)
Das kannst du so machen:
INSERT INTO DENI/FRIEN01P
SELECT
RCRDID+112,
PROFESION,
NAME,
SURNAME,
AGE,
RCRDTYP,
RCRDLCU,
RCRDLCT,
RCRDLCD
FROM
FRIEN01P
Dort anstelle von 112 sollten Sie die maximale ID in der Tabelle DENI/FRIEN01P angeben.
Ich habe das gleiche Problem, wo ein einzelnes Skript mit einer Tabelle funktionieren soll, deren Spalten regelmäßig von anderen Entwicklern hinzugefügt werden. Nicht nur das, ich unterstütze viele verschiedene Versionen unserer Datenbank, da die Kunden unter Umständen nicht alle mit der aktuellen Version auf dem neuesten Stand sind.
Ich habe die Lösung von Jonas genommen und etwas modifiziert. Dadurch kann ich eine Kopie der Zeile erstellen und dann den Primärschlüssel ändern, bevor er wieder in die ursprüngliche Quelltabelle eingefügt wird. Dies ist auch sehr praktisch für das Arbeiten mit Tabellen, die keine NULL-Werte in Spalten zulassen, und Sie müssen nicht jeden Spaltennamen in INSERT angeben müssen.
Dieser Code kopiert die Zeile für 'ABC' nach 'XYZ'
SELECT * INTO #TempRow FROM SourceTable WHERE KeyColumn = 'ABC';
UPDATE #TempRow SET KeyColumn = 'XYZ';
INSERT INTO SourceTable SELECT * FROM #TempRow;
DELETE #TempRow;
Wenn Sie mit dem Ablegen der Temp-Tabelle fertig sind.
DROP TABLE #TempRow;
So habe ich es mit ASP classic gemacht und konnte nicht mit den obigen Antworten arbeiten. Ich wollte ein Produkt in unserem System auf eine neue product_id kopieren können und brauchte es selbst wenn wir der Tabelle mehr Spalten hinzufügen.
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")
Meine Tabelle enthält 100 Felder, und ich brauchte eine Abfrage, um nur arbeiten zu können. Jetzt kann ich mit einer grundlegenden bedingten Logik eine beliebige Anzahl von Feldern ausschalten und muss mich nicht um die Ordnungsposition kümmern.
Ersetzen Sie den folgenden Tabellennamen durch Ihren Tabellennamen
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")
Ersetzen Sie den ursprünglichen Identitätsfeldnamen durch Ihren PK-Feldnamen
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
Ersetzen Sie die Tabellennamen erneut (sowohl den Zieltabellennamen als auch den Namen der Quellentabelle). Bearbeiten Sie Ihre where
-Bedingungen
SQL = "INSERT INTO TARGET-TABLE-NAME (" & columnListTARGET & ") SELECT " & columnListSOURCE & " FROM SOURCE-TABLE-NAME WHERE (FIELDNAME = FIELDVALUE)"
Conn.Execute(SQL)