我试着做这个查询

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


当前回答

如果存在Identity列,则必须指定要插入的列名。 所以命令如下所示:

SET IDENTITY_INSERT DuplicateTable ON

INSERT Into DuplicateTable ([IdentityColumn], [Column2], [Column3], [Column4] ) 
SELECT [IdentityColumn], [Column2], [Column3], [Column4] FROM MainTable

SET IDENTITY_INSERT DuplicateTable OFF

如果您的表有很多列,则使用此命令获取这些列的名称。

SELECT column_name + ','
FROM   information_schema.columns 
WHERE  table_name = 'TableName'
for xml path('')

(删除最后一个逗号(','))只需复制过去的列名。

其他回答

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

我认为这个错误是由于表定义中的列数和插入查询中的列数不匹配造成的。此外,输入的值省略了列的长度。 因此,只需检查表定义来解决这个问题

两者都可以工作,但如果使用#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,....)

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

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);