我想将Table A
中的1行复制到Table A2
。
这是我的代码:
Insert into A2
select * from A1
where ID=290
Id
是Primary Key
,两个表都具有相同的结构。
显然上面的代码失败了,因为它无法插入Primary Key
(我不想要它,我希望生成一个新的PK
。
我知道我可以使用显式插入,但这是一个包含数百列的非常宽的表。
有没有办法插入期望ID
Primary Key
的所有列?
否:这不是解决方案。请花1分钟时间仔细阅读问题然后关闭它们!
我说我知道这可以通过显式插入来实现。我想知道是否可以用更短的SQL来完成,因为这是一个非常宽的表。
如果您有解决方案,请在此处提及参考资料。
答案 0 :(得分:2)
没有select * except some columns
。您的sql必须包含除两个表的id之外的完整列列表。
但是,这并不意味着您必须手动输入它们。您可以从sys.columns
或information_schema.columns
中选择列列表来生成列列表
如果您使用的是SSMS,则可以展开其中一个表的列列表,只需将列拖到查询窗口即可。如果要将它们全部拖动,只需将列“文件夹”图标拖到查询窗口即可。
答案 1 :(得分:1)
嗯,这可能有点矫枉过正,但它会做你想要的。这样,无论表格有多大(添加/删除列),您都可以获得精确的副本。
编辑:在回应下面的评论时,为了充分披露,PK必须是一个标识,列必须是相同的顺序。
SELECT * INTO #TMP FROM A1 WHERE ID = <THE ID YOU WANT>
ALTER TABLE #TMP DROP COLUMN ID
INSERT INTO A2
SELECT * FROM #TMP
DROP TABLE #TMP
答案 2 :(得分:1)
你真的应该只指定列表。
如果您担心意外遗漏某列,可以使用SQL为您生成列列表:
declare @columnList NVARCHAR(MAX)
select @columnList = ISNULL(@columnList + N', [', N'[') + [COLUMN_NAME] + N']' from INFORMATION_SCHEMA.COLUMNS where [TABLE_NAME] = 'a1' and [COLUMN_NAME] not in ('Id')
print @columnList
如果您确实需要一个语句来执行您所要求的操作,您可以扩展上述内容以动态生成和执行SQL。不幸的是,这更难以阅读,但它确实具有在添加列时自动调整的好处。
declare @dynamicSql NVARCHAR(MAX)
declare @columnList NVARCHAR(MAX)
select @columnList = ISNULL(@columnList + N', [', N'[') + [COLUMN_NAME] + N']' from INFORMATION_SCHEMA.COLUMNS where [TABLE_NAME] = 'a1' and [COLUMN_NAME] not in ('Id')
set @dynamicSql = N'INSERT INTO [a1](' + @columnList + N') SELECT ' + @columnList + N' FROM [a2] WHERE [Id] = 290'
exec(@dynamicSql)