我试着做这个查询
INSERT INTO dbo.tbl_A_archive
SELECT *
FROM SERVER0031.DB.dbo.tbl_A
但即使在我跑了之后
set identity_insert dbo.tbl_A_archive on
我得到这个错误消息
表'dbo中标识列的显式值。tbl_A_archive'只能在使用列列表且IDENTITY_INSERT为ON时指定。
tbl_A是一个行和宽都很大的表,也就是说它有很多列。我不想手动输入所有的列。我怎样才能让它工作呢?
SET IDENTITY_INSERT tableA ON
你必须为INSERT语句创建一个列列表:
INSERT Into tableA ([id], [c2], [c3], [c4], [c5] )
SELECT [id], [c2], [c3], [c4], [c5] FROM tableB
不像“INSERT Into tableA SELECT ........”
SET IDENTITY_INSERT tableA OFF
这应该有用。我刚碰到你的问题
SET IDENTITY_INSERT dbo.tbl_A_archive ON;
INSERT INTO dbo.tbl_A_archive (IdColumn,OtherColumn1,OtherColumn2,...)
SELECT *
FROM SERVER0031.DB.dbo.tbl_A;
SET IDENTITY_INSERT dbo.tbl_A_archive OFF;
不幸的是,似乎您确实需要包含标识列的列列表来插入指定标识的记录。但是,您不必在SELECT中列出列。
正如@Dave Cluderay建议的那样,这将导致一个格式化的列表供您复制和粘贴(如果小于200000字符)。
我添加了USE,因为我要在实例之间切换。
USE PES
SELECT SUBSTRING(
(SELECT ', ' + QUOTENAME(COLUMN_NAME)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'Provider'
ORDER BY ORDINAL_POSITION
FOR XML path('')),
3,
200000);
如果您想通过存储过程将值从一个表插入到另一个表。我用了这个和这个,后者和Andomar的答案差不多。
CREATE procedure [dbo].[RealTableMergeFromTemp]
with execute as owner
AS
BEGIN
BEGIN TRANSACTION RealTableDataMerge
SET XACT_ABORT ON
DECLARE @columnNameList nvarchar(MAX) =
STUFF((select ',' + a.name
from sys.all_columns a
join sys.tables t on a.object_id = t.object_id
where t.object_id = object_id('[dbo].[RealTable]')
order by a.column_id
for xml path ('')
),1,1,'')
DECLARE @SQLCMD nvarchar(MAX) =N'INSERT INTO [dbo].[RealTable] (' + @columnNameList + N') SELECT * FROM [#Temp]'
SET IDENTITY_INSERT [dbo].[RealTable] ON;
exec(@sqlcmd)
SET IDENTITY_INSERT [dbo].[RealTable] OFF
COMMIT TRANSACTION RealTableDataMerge
END
GO