我试着做这个查询

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是一个行和宽都很大的表,也就是说它有很多列。我不想手动输入所有的列。我怎样才能让它工作呢?


当前回答

如果“归档”表是您的主表的精确副本,那么我只是建议您删除id是标识列的事实。这样你就可以插入它们了。

或者,您可以使用以下语句允许和禁止对表进行标识插入

SET IDENTITY_INSERT tbl_A_archive ON
--Your inserts here
SET IDENTITY_INSERT tbl_A_archive OFF

最后,如果您需要标识列按原样工作,那么您总是可以运行存储的过程。

sp_columns tbl_A_archive 

这将返回表中的所有列,然后您可以将其剪切并粘贴到您的查询中。(这几乎总是比使用*更好)

其他回答

有一个或多个列具有自动递增属性,或者该属性的值将作为约束计算。你要修改这一列。

有两种解决方法 1)显式地提到其他列并只设置它们的值,PrimaryKey或自动递增列值将自动设置。

2)您可以打开IDENTITY_INSERT,然后执行插入查询,最后关闭IDENTITY_INSERT。

建议:按照第一步进行,因为这是更合适和有效的方法。

要了解更多信息,请阅读关于SQL-helper的文章。

如果您想通过存储过程将值从一个表插入到另一个表。我用了这个和这个,后者和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

同意海因茨的回答。对于第一个第二个选项,下面是一个查询,它在表中生成一个逗号分隔的列列表:

select name + ', ' as [text()] 
from sys.columns 
where object_id = object_id('YourTable') 
for xml path('')

对于大的表格,这可以节省大量的打字工作:)

如果您正在使用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仍然会出错,那么就使用#2

1)

SET IDENTITY_INSERT customers ON
GO
insert into dbo.tbl_A_archive(id, ...)
SELECT Id, ...
FROM SERVER0031.DB.dbo.tbl_A

2)

SET IDENTITY_INSERT customers ON
GO
insert into dbo.tbl_A_archive(id, ...)
VALUES(@Id,....)