我试着做这个查询

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


当前回答

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

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

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

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

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

其他回答

请确保从中选择记录的表中的列名、数据类型和顺序与目标表完全相同。唯一的区别应该是目标表有一个标识列作为第一列,这在源表中是没有的。

当我执行“INSERT INTO table_Dest SELECT * FROM table_source_linked_server_excel”时,我也遇到了类似的问题。表格有115列。

I had two such tables where I was loading data from Excel (As linked server) into tables in database. In database tables, I had added an identity column called 'id' that was not there in source Excel. For one table the query was running successfully and in another I got the error "An explicit value for the identity column in table can only be specified when a column list is used and IDENTITY_INSERT is ON SQL Server". This was puzzling as the scenario was exactly same for both the queries. So I investigated into this and what I found was that in the query where I was getting error with INSERT INTO .. SELECT *:

源表中的一些列名被修改,但值是正确的 SELECT *所选择的实际数据列之外还有一些额外的列。我通过使用源Excel表(链接服务器下)上的“脚本表作为>选择>新查询窗口”选项发现了这一点。在Excel中,在最后一列之后有一个隐藏列,尽管它没有任何数据。我在源Excel表格中删除了该列并保存了它。

在做了以上两个更改之后,INSERT INTO…SELECT *运行成功。目标表中的标识列按照预期为每个插入的行生成标识值。

因此,即使目标表可能有源表中没有的标识列,INSERT INTO..如果源和目标中的名称、数据类型和列顺序完全相同,则SELECT *将成功运行。

希望它能帮助到别人。

两者都可以工作,但如果使用#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语句的逗号分隔列表中,我使用了以下选项,因为它们比这里的大多数响应更简洁。然而,这里的大多数回答仍然是完全可以接受的。

1)

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

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

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

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

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