This question接近我的需要,但我的情况略有不同。源表和目标表是相同的,主键是uniqueidentifier(guid)。当我尝试这个时:
insert into MyTable
select * from MyTable where uniqueId = @Id;
我显然遇到了主键约束违规,因为我试图复制主键。实际上,我根本不想复制主键。相反,我想创建一个新的。另外,我想有选择地复制某些字段,并将其他字段留空。为了使事情变得更复杂,我需要获取原始记录的主键,并将其插入副本中的另一个字段(PreviousId字段)。
我确信有一个简单的解决方案,我只是不知道足够的TSQL知道它是什么。
答案 0 :(得分:171)
试试这个:
insert into MyTable(field1, field2, id_backup)
select field1, field2, uniqueId from MyTable where uniqueId = @Id;
未指定的任何字段都应该接收其默认值(未定义时通常为NULL)。
答案 1 :(得分:79)
好的,我知道这是一个老问题,但无论如何我都会发布我的答案。
我喜欢这个解决方案。我只需要指定标识列。
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” - 列是标识列,这是我必须指定的唯一列。无论如何,它比其他方式更好。 : - )
我使用SQL Server。您可能希望在第1行和第2行使用“CREATE TABLE
”和“UPDATE TABLE
”。
嗯,我看到我没有给出他想要的答案。他也希望将id复制到另一列。但是这个解决方案很适合制作一个带有新auto-id的副本。
我用Michael Dibbets的idéas编辑我的解决方案。
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应该替换为您的名字(当然)。
答案 2 :(得分:11)
我猜你在试图避免写出所有的列名。如果您正在使用SQL Management Studio,您可以轻松地右键单击表格和脚本为插入...然后您可以使用该输出来创建查询。
答案 3 :(得分:10)
指定除ID字段以外的所有字段。
INSERT INTO MyTable (FIELD2, FIELD3, ..., FIELD529, PreviousId)
SELECT FIELD2, NULL, ..., FIELD529, FIELD1
FROM MyTable
WHERE FIELD1 = @Id;
答案 4 :(得分:3)
我遇到了同样的问题,我希望单个脚本能够处理其他开发人员定期添加列的表。不仅如此,我支持我们数据库的许多不同版本,因为客户可能不会都与当前版本保持同步。
我接受了乔纳斯的解决方案并略微修改了它。这允许我复制该行,然后在将其添加回原始源表之前更改主键。这对于使用不允许列中的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;
答案 5 :(得分:2)
insert into MyTable (uniqueId, column1, column2, referencedUniqueId)
select NewGuid(), // don't know this syntax, sorry
column1,
column2,
uniqueId,
from MyTable where uniqueId = @Id
答案 6 :(得分:1)
如果“key”是您的PK字段并且它是自动数字。
insert into MyTable (field1, field2, field3, parentkey)
select field1, field2, null, key from MyTable where uniqueId = @Id
它将生成一条新记录,从原始记录中复制field1和field2
答案 7 :(得分:1)
我的表有100个字段,我需要一个查询才能正常工作。现在我可以用一些基本的条件逻辑切换出任意数量的字段,而不用担心它的序数位置。
将以下表名替换为您的表名
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")
用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
再次替换表名(目标表名和源表名);修改您的where
条件
SQL = "INSERT INTO TARGET-TABLE-NAME (" & columnListTARGET & ") SELECT " & columnListSOURCE & " FROM SOURCE-TABLE-NAME WHERE (FIELDNAME = FIELDVALUE)"
Conn.Execute(SQL)
答案 8 :(得分:1)
我知道我的答案迟到了。但我解决的方式与所有答案有点不同。
我有一种情况,我需要在表中克隆除少数列之外的行。少数人会有新的价值观。此过程应自动支持将来对表的更改。这意味着,克隆记录而不指定任何列名。
我的方法是,
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)
答案 9 :(得分:0)
你可以这样做:
INSERT INTO DENI/FRIEN01P
SELECT
RCRDID+112,
PROFESION,
NAME,
SURNAME,
AGE,
RCRDTYP,
RCRDLCU,
RCRDLCT,
RCRDLCD
FROM
FRIEN01P
而不是112,你应该在表DENI / FRIEN01P中放入一些最大id。
答案 10 :(得分:0)
这是我使用ASP Classic进行的操作,无法完全与上面的答案一起使用,我希望能够将系统中的产品复制到新的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")