Copy row but with new id
Let us say your table has following fields:
( pk_id int not null auto_increment primary key,
col1 int,
col2 varchar(10)
)
then, to copy values from one row to the other row with new key value,
following query may help
insert into my_table( col1, col2 ) select col1, col2 from my_table where pk_id=?;
This will generate a new value for pk_id
field and copy values from col1
, and col2
of the selected row.
You can extend this sample to apply for more fields in the table.
UPDATE:
In due respect to the comments from JohnP and Martin -
We can use temporary table to buffer first from main table and use it to copy to main table again.
Mere update of pk reference field in temp table will not help as it might already be present in the main table. Instead we can drop the pk field from the temp table and copy all other to the main table.
With reference to the answer by Tim Ruehsen in the referred posting:
CREATE TEMPORARY TABLE tmp SELECT * from my_table WHERE ...;
ALTER TABLE tmp drop pk_id; # drop autoincrement field
# UPDATE tmp SET ...; # just needed to change other unique keys
INSERT INTO my_table SELECT 0,tmp.* FROM tmp;
DROP TEMPORARY TABLE tmp;
Hope this helps.
Copy row with one field changed and new autogenerated id in MySQL
SELECT *
is antipattern. You should explicitly set columns:
INSERT INTO original(col1, col2, ...) --skip id column
SELECT col1, col2, ...
FROM temp1;
Or even better skip the temp1 table at all. Single statement solution:
INSERT INTO original(col1, col2, ..., field) -- skip id column
SELECT col1, col2, ..., 'new_value'
FROM original
WHERE field='old value';
To get what you want you need mechanism like Oracle DEFAULT Values On Explicit NULLs.
But even then you need to drop column from temp1, because:
INSERT INTO original -- only N column
SELECT NULL as id, * -- this will return N+1 columns
FROM temp1;
So you have to use:
ALTER TABLE temp1 DROP COLUMN id;
-- now columns match
INSERT INTO original -- only N column
SELECT NULL as id, * -- this will return N columns and
-- NULL is handled by DEFAULT ON NULL
FROM temp1;
How do you copy a record in a SQL table but swap out the unique id of the new row?
Try this:
insert into MyTable(field1, field2, id_backup)
select field1, field2, uniqueId from MyTable where uniqueId = @Id;
Any fields not specified should receive their default value (which is usually NULL when not defined).
SQL Server : copy row and Insert into to the same table but with a different ID
Since LOAD_NO
is an identity column, you should not be specifying a value for it when inserting. So you need to modify our INSERT
statement to not include the LOAD_NO
column - something like this:
INSERT INTO LOADS(col1, col2, ..., colN) -- all columns *EXCEPT* LOAD_NO
SELECT col1, col2, ...., colN -- all columns *EXCEPT* LOAD_NO
FROM LOADS_TempTable;
SQL Server will automatically assign a new LOAD_NO
to the row you're inserting - after all, that's the job of the identity column!
Copy row, and dependent rows in another table, and dependent rows in another, etc
You need to capture the new 'id' values as you insert into each table to use them for the foreign key references in the child tables. The most reliable way to capture the new 'id's is using the SQL output clause as that will always give the correct ids and can handle multiple ids (many of the other approaches to obtaining the newly created record id have pitfalls worth avoiding).
You also want to wrap it in a transaction to ensure its an all or nothing operation (you may also want additional error handling).
Because the output
clause on an insert
statement doesn't allow values from the original table I've used a merge
statement for the second part, with a match condition of 1=0
i.e. it will never match and therefore always insert, and the merge
statement does allow values from the original table in the output
clause.
declare @Id int = 123;
declare @ItemOutput table (IdNew int);
declare @ItemOptionOutput table (IdNew int, IdOld int);
begin tran;
insert into dbo.items (title)
output Inserted.id into @ItemOutput
select title
from dbo.items I
where I.id = @Id;
MERGE INTO dbo.item_options as [Target]
USING (select id, [Option], (select IdNew from @ItemOutput) from dbo.item_options) AS [Source] (id, [Option], IdNew)
ON 1 = 0
WHEN NOT MATCHED THEN
INSERT (itemID, [Option])
VALUES ([Source].IdNew, [Source].[Option])
OUTPUT Inserted.id, [Source].id
INTO @ItemOptionOutput (IdNew, IdOld);
insert into dbo.sub_options (item_optionsID, subOption)
select (select O.IdNew from @ItemOptionOutput O where O.IdOld = SO.ID), SubOption
from dbo.sub_options SO
where SO.id in (select O.id from dbo.item_options O where O.ItemID = @Id);
commit;
Copy rows from the same table and update the ID column
INSERT INTO ProductDefinition (ProdID, Definition, Desc)
SELECT
xxx, Definition, Desc
FROM
ProductDefinition
WHERE
ProdID = yyy
The xxx
is your new ProdID and the yyy
is your old one. This also assumes that DefID
is automagically populated on INSERT
.
How to copy rows with SQL and get new and old IDs as result?
With helpful links from Andriy M's link to 'How to copy tables avoiding cursors in SQL?', I managed to come up with this very elegant solution:
DECLARE @t TABLE (oID int, nID int);
MERGE T s
USING (
SELECT TID, name, address
FROM T [s]
) d on 0 = 1
WHEN NOT MATCHED
THEN INSERT (name, address)
VALUES (name, address)
OUTPUT d.TID as oID, Inserted.TID as nID
INTO @t;
Related Topics
Mysql Truncated Incorrect Double Value
Pg Copy Error: Invalid Input Syntax for Integer
How to Select the Oldest Date With Ties
How to Select Rows With Only Numeric Characters in Oracle SQL
Sql to Find Upper Case Words from a Column
Mysql - How to Use Like on Multiple Columns
T-Sql Query to Get the String Between Two Special Characters
How to Set Timezone for Postgres Psql
How to Resolve MySQL Error Code: 1292. Truncated Incorrect Double Value
Joining the Table Conditionally in SQL
Sql Server:How to Test If a String Has Only Digit Characters
Max and Min Sal With Employee Name in One Query
How to Insert 1000 Rows At a Time
How to Specify a Password to 'Psql' Non-Interactively
Calculate Total Working Hour of Employee in SQL With Only 1 Column