我试着做这个查询
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是一个行和宽都很大的表,也就是说它有很多列。我不想手动输入所有的列。我怎样才能让它工作呢?
如果您想通过存储过程将值从一个表插入到另一个表。我用了这个和这个,后者和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
这应该有用。我刚碰到你的问题
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);
如果您正在使用SQL Server Management Studio,您不必自己键入列列表-只需在对象资源管理器中右键单击表,并选择脚本表作为-> SELECT到->新建查询编辑器窗口。
如果你不是,那么类似的查询应该有助于作为一个起点:
SELECT SUBSTRING(
(SELECT ', ' + QUOTENAME(COLUMN_NAME)
FROM INFORMATION_SCHEMA.COLUMNS
WHERE TABLE_NAME = 'tbl_A'
ORDER BY ORDINAL_POSITION
FOR XML path('')),
3,
200000);
有一个或多个列具有自动递增属性,或者该属性的值将作为约束计算。你要修改这一列。
有两种解决方法
1)显式地提到其他列并只设置它们的值,PrimaryKey或自动递增列值将自动设置。
2)您可以打开IDENTITY_INSERT,然后执行插入查询,最后关闭IDENTITY_INSERT。
建议:按照第一步进行,因为这是更合适和有效的方法。
要了解更多信息,请阅读关于SQL-helper的文章。