How do you copy a record in a SQL table but swap out the unique id of the new row?

This question comes close to what I need, but my scenario is slightly different. The source table and destination table are the same and the primary key is a uniqueidentifier (guid). When I try this:

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

I obviously get a primary key constraint violation, since I'm attempting to copy over the primary key. Actually, I don't want to copy over the primary key at all. Rather, I want to create a new one. Additionally, I would like to selectively copy over certain fields, and leave the others null. To make matters more complex, I need to take the primary key of the original record, and insert it into another field in the copy (PreviousId field).

I'm sure there is an easy solution to this, I just don't know enough TSQL to know what it is.

204325 次浏览

试试这个:


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).

指定除 ID 字段以外的所有字段。

INSERT INTO MyTable (FIELD2, FIELD3, ..., FIELD529, PreviousId)
SELECT FIELD2, NULL, ..., FIELD529, FIELD1
FROM MyTable
WHERE FIELD1 = @Id;
insert into MyTable (uniqueId, column1, column2, referencedUniqueId)
select NewGuid(), // don't know this syntax, sorry
column1,
column2,
uniqueId,
from MyTable where uniqueId = @Id

如果“键”是你的 PK 字段,它是自动数字的。

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

它将生成一个新记录,从原始记录中复制 field1和 field2

我猜你是想避免把所有栏名都写出来。如果您正在使用 SQLManagementStudio,则可以轻松右键单击表并将脚本作为插入。.然后您可以随意处理该输出以创建查询。

你可以这样做:

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

您应该在表 DENI/FRIEN01P 中放置一个最大 id 的数字,而不是112。

我的表有100个字段,我需要一个查询才能正常工作。现在我可以用一些基本的条件逻辑切换掉任意数量的字段,而不用担心它的序数位置。

  1. 用表名替换下面的表名

    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. Replace the original identity field name with your PK field name

    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. Replace the table names again (both target table name and source table name); edit your where conditions

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

好吧,我知道这是一个老问题,但我张贴了我的答案。

我喜欢这个解决方案。我只需要指定标识列。

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;

“ id”-column 是标识列,这是我必须指定的唯一一列。反正总比反过来好。:-)

我使用 SQLServer。您可能希望在第1行和第2行使用“ CREATE TABLE”和“ UPDATE TABLE”。 嗯,我发现我并没有给出他想要的答案。他还想将 id 复制到另一列。但是这个解决方案很适合使用新的自动标识进行复制。

我用 Michael Dibbet 的想法编辑我的解决方案。

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;

您可以通过使用“ ,”分隔多个列来删除它们。 Id 应该替换为要复制的行的 id。 MyDatabase,MyTable 和 IndexField 应该被你的名字替换(当然)。

我也有同样的问题,我希望一个脚本能够处理一个由其他开发人员定期添加列的表。不仅如此,我还支持我们数据库的许多不同版本,因为客户可能并不都是当前版本的最新版本。

我采用了乔纳斯的解决方案,并稍作修改。这允许我复制该行,然后在将其添加回原始源表之前更改主键。这对于处理不允许在列中使用 NULL 值并且不希望在 INSERT 中指定每个列名的表也非常方便。

此代码将“ ABC”的行复制到“ XYZ”

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

完成删除临时表之后。

DROP TABLE #TempRow;

我知道我的回答迟到了。但我解决问题的方法和所有的答案都不一样。

我有一个情况,我需要克隆一个表中的一行,除了少数几列。这些少数将有新的价值观。这个过程应该自动支持将来对表的更改。这意味着,在不指定任何列名的情况下克隆记录。

我的方法是,

  1. 查询 Sys.Columns 以获取表的完整列表并包含列名 在 where 子句中跳过的列。
  2. 将其转换为 CSV 作为列名。
  3. 构建选择... 基于此插入到脚本中。


括号@columnsToCopyValue varchar (max) ,@query varchar (max)
SET@columnsToCopyValue =”

--获取要排除的所有执行列 Identity 列和 Other 列。比如 IndentityColumn,Column1,Column2 从 sys.column c 中选择@columnsToCopyValue =@columnsToCopyValue + [ name ] +’,’其中 c.OBJECT _ id = OBJECT _ ID (‘ YourTableName’) ,名称不在(‘ IndentityColumn’,‘ Column1’,‘ Column2’)中 选择@columnsToCopyValue = SUBSTRING (@columnsToCopyValue,0,LEN (@columnsToCopyValue)) Print@columnsToCopyValue

从 YourTableName 中选择@query = CONCAT (‘ insert into YourTableName (’,@columnsToCopyValue,’,Column1,Column2) Select’,@columnsToCopyValue,’,“ Value1”,“ Value2”,’,’,’,从 YourTableName 中的 IndentityColumn =’”,@search变量,“”)

Print@query Exec (@query)

下面是我是如何使用 ASP 经典来完成这项工作的,但是我不能让它与上面的答案一起工作,我想要能够在我们的系统中将一个产品复制到一个新的 product _ id,并且需要它能够工作,即使我们添加更多的列到表中。

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")