我试着做这个查询

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


当前回答

对于SQL语句,还必须指定列列表。如。

INSERT INTO tbl (idcol1,col2) VALUES ( value1,value2)

而不是

INSERT INTO tbl VALUES ( value1,value2)

其他回答

表中标识列的显式值只能为 指定的时间是……”

解决这个问题的方法是不指定单位列。

所以与其

INSERT INTO dbo.tbl_A_archive
  SELECT *
 FROM SERVER0031.DB.dbo.tbl_A

我指定了所有列,但没有指定标识列(tbl_A_archive.ID)

INSERT INTO dbo.tbl_A_archive
  SELECT col1, col2, colETC
 FROM SERVER0031.DB.dbo.tbl_A

对于SQL语句,还必须指定列列表。如。

INSERT INTO tbl (idcol1,col2) VALUES ( value1,value2)

而不是

INSERT INTO tbl VALUES ( value1,value2)

如果存在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('')

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

为了将所有列名填充到这个问题的解决方案的Select语句的逗号分隔列表中,我使用了以下选项,因为它们比这里的大多数响应更简洁。然而,这里的大多数回答仍然是完全可以接受的。

1)

SELECT column_name + ',' 
FROM   information_schema.columns 
WHERE  table_name = 'YourTable'

2)这可能是创建列最简单的方法, 如果你有SQL Server SSMS。

1)在对象资源管理器中打开表,单击表名左侧的“+”或双击表名打开子列表。 2)将列子文件夹拖到主查询区,它将为您自动生成整个列列表。

我使用以下命令创建一个与表完全相同但没有标识的临时表:

SELECT TOP 0 CONVERT(INT,0)myid,* INTO #temp FROM originaltable

ALTER TABLE #temp DROP COLUMN id

EXEC tempdb.sys.sp_rename N'#temp.myid', N'id', N'COLUMN'

得到关于重命名的警告,但没什么大不了的。 我在生产类系统中使用这种方法。有助于确保复制将跟随将来的任何表修改,并且所产生的临时文件能够在任务中获得额外的行。请注意,PK约束也被删除了-如果你需要它,你可以在最后添加它。