当IDENTITY_INSERT设置为OFF时,无法为表'table'中的标识列插入显式值


361

执行以下脚本时出现以下错误。错误是什么,如何解决?

Insert table(OperationID,OpDescription,FilterID)
values (20,'Hierachy Update',1)

错误:

服务器:消息544,级别16,状态1,第1行

当IDENTITY_INSERT设置为OFF时,无法在表'table'中为标识列插入显式值。



2
@HimanshuAhuja这个问题(1334012)已有10年的历史,您仅链接了1个问题。如果有的话,更新的是重复的。但是仔细观察,您会发现它们有所不同(新版本将IDENTITY_INSERT指定为ON)。请删除您的标志/评论。
jasie

@jasie会这样做,因为我不记得我发布此标志的时候
Himanshu Ahuja

Answers:


467

您正在为此插入OperationId一个标识列的值。

您可以像这样在表上打开标识插入,以便可以指定自己的标识值。

SET IDENTITY_INSERT Table1 ON

INSERT INTO Table1
/*Note the column list is REQUIRED here, not optional*/
            (OperationID,
             OpDescription,
             FilterID)
VALUES      (20,
             'Hierachy Update',
             1)

SET IDENTITY_INSERT Table1 OFF 

14
+1准确-关闭该选项允许显式插入ON,然后再插入,然后打开选项OFF再次
marc_s

13
如果您确实想将值添加到标识列,这就是您的答案,但是另一方面,有人将列设置为在插入时自行递增。在这种情况下,该表将跟踪下一个空闲号码,您无需自己生成OperationID。可以通过SELECT SCOPE_IDENTITY()获取新的ID。
哈坎·温瑟

15
危险的实践,建议不要在没有警告的情况下使用它,而不建议这样做。答案很差。
HLGEM 2011年

7
很好的答案,但请确保您知道自己在做什么。对我来说,用需要在不同表上匹配外键的数据为数据库播种很有用
Berty 2014年

2
@UlyssesAlves:只能在数据库范围内的单个表上启用此选项-因此,如果将其保留在一个表上,则将永远无法使用该选项。另外:这不是一个应该保留的选项-默认情况下,您应该让SQL Server处理身份值-这是在非常特殊的情况下的最后手段-而不是在以下位置保留或保留的通用选项:您的休闲...
marc_s


46

简单来说,如果您在SQL Server上收到此错误,则运行此查询-

SET IDENTITY_INSERT tableName ON

这仅在单个数据库表中工作, 例如,如果表名是student,则查询如下 SET IDENTITY_INSERT student ON

如果您在Web应用程序上遇到此错误或使用实体框架,则首先在SQL Server上运行此查询并更新您的实体模型(.edmx file 并构建您的项目,此错误将得到解决


在带有EF的MVC Web应用程序中就是这种情况,我只是从.edmx中删除了模型,然后重新添加了该模型(从数据库中右键单击更新模型),然后清理并重建了对我有用的项目。谢谢@Umang Patwa
Ishwor Khanal

42

小心将IDENTITY_INSERT设置为ON。除非数据库处于维护模式并设置为单用户,否则这是一个不好的做法。这不仅会影响您的插入内容,还会影响其他尝试访问该表的人。

您为什么要在身份字段中输入一个值?


5
以什么方式影响?这是会话级别的选项,不是表的属性。
马丁·史密斯

5
您要维护关系的两个数据库之间的一次数据同步。例如,我使用它将我的产品架构从一个数据库拉到另一个数据库
NSjonas 2013年

1
@NSjonas,可以很好地将Identity _insert table1设置为ON。我见过一些人想要使用此功能从应用程序中执行某些操作,这些操作应通过简单的插入操作并允许生成标识。
HLGEM

2
问题是“您能否指定它是什么以及如何解决?” 您的答案是引起警告和其他问题的注释,而不是解决问题的正确答案。
Quality Catalyst

是的,不要在主键中插入值。
doflamingo '17

22

基本上有2种不同的方式来插入记录而不会出错:

1)当IDENTITY_INSERT设置为OFF时。必须不存在主键“ ID”

2)当IDENTITY_INSERT设置为ON时。必须存在主键“ ID”

根据以下示例,该示例是使用IDENTITY PRIMARY KEY创建的同一张表中的示例:

CREATE TABLE [dbo].[Persons] (    
    ID INT IDENTITY(1,1) PRIMARY KEY,
    LastName VARCHAR(40) NOT NULL,
    FirstName VARCHAR(40)
);

1)在第一个示例中,当IDENTITY_INSERT为OFF时,可以将新记录插入表中而不会出现错误。绝不能在“ INSERT INTO”语句中出现主键“ ID”,并且唯一的ID值将自动添加:。如果在这种情况下从INSERT提供了ID,则会收到错误“无法为表中的标识列插入显式值...”。

SET IDENTITY_INSERT [dbo].[Persons] OFF;
INSERT INTO [dbo].[Persons] (FirstName,LastName)
VALUES ('JANE','DOE'); 
INSERT INTO Persons (FirstName,LastName) 
VALUES ('JOE','BROWN');

表[dbo]的输出。[人]为:

ID    LastName   FirstName
1     DOE        Jane
2     BROWN      JOE

2)在第二个示例中,当IDENTITY_INSERT为ON时,可以将新记录插入表中而不会出现错误。只要ID值不存在,则必须从“ INSERT INTO”语句中提供主键“ ID”:如果在这种情况下INSERT中不存在ID,则将收到错误消息“ Explicit value必须为为标识列表指定...”

SET IDENTITY_INSERT [dbo].[Persons] ON;
INSERT INTO [dbo].[Persons] (ID,FirstName,LastName)
VALUES (5,'JOHN','WHITE'); 
INSERT INTO [dbo].[Persons] (ID,FirstName,LastName)
VALUES (3,'JACK','BLACK'); 

表[dbo]的输出。[人]为:

ID    LastName   FirstName
1     DOE        Jane
2     BROWN      JOE
3     BLACK      JACK
5     WHITE      JOHN

2
再加上一个用于实际解释该标记如何工作​​的标记。保存了我的一天,超人
约翰·约翰(John John)

20

在该表的实体中,将DatabaseGenerated属性添加到设置了身份插入的列上方:

例:

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int TaskId { get; set; }

好吧,是的,但是我真的想要EF的答案:-)不过,这对于可能从未使用过,甚至可能从未使用过EF的OP是不合适的。
Auspex

无论如何,答案都是错误的。我的实体已经用指定DatabaseGeneratedOption.Identity,但仍然出现错误。这是我自己的错,我将伪ID放在新行中以在网页上将它们彼此区分开,并且我希望在insert足够之前先将其无效。
Auspex

13

例如,如果您的表名是School,则可以简单地使用此语句。在插入之前,请确保将identity_insert设置为ON,然后在插入查询之后将 identity_insert设置为 OFF

SET IDENTITY_INSERT School ON
/*
  insert query
  enter code here
*/
SET IDENTITY_INSERT School OFF

1
您能否在答案上稍加扩展,以包括该命令的说明,其作用原理以及其作用?
gareththegeek

@gareththegeek是的,对于identity列,您必须确保插入数据。

6

如果您使用liquibase来更新SQL Server,则可能尝试将记录键插入到autoIncrement字段中。通过从插入中删除该列,您的脚本应运行。

<changeSet id="CREATE_GROUP_TABLE" >
    <createTable tableName="GROUP_D">
        <column name="GROUP_ID" type="INTEGER" autoIncrement="true">
            <constraints primaryKey="true"/>
        </column>
    </createTable>
</changeSet>

<changeSet id="INSERT_UNKNOWN_GROUP" >
    <insert tableName="GROUP_D">    

        <column name="GROUP_ID" valueNumeric="-1"/>
 ...
    </insert>
</changeSet>

4

您的查询中有前面提到的OperationId,它不应该自动提示

Insert table(OperationID,OpDescription,FilterID)
values (20,'Hierachy Update',1)

因此您的查询将是

Insert table(OpDescription,FilterID)
values ('Hierachy Update',1)

3

另一种情况是检查主键是否与您的班级相同,唯一的区别是主键上附加了“ ID”,或在主键上指定与主键无关的[Key]。类被命名。


2
  1. 当您有一个(主键)列在SQL中未设置为Is Identity为true,并且在插入过程中未传递其显式值时,会发生这种情况。它将占据第一行,然后您将无法插入第二行,错误将弹出。可以通过[DatabaseGenerated(DatabaseGeneratedOption.Identity)]在PrimaryKey列中添加以下代码行并确保将其设置为数据类型int来更正此错误。如果列是主键,并且在SQL中将IsIDentity设置为true,则不需要此代码行[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
  2. 当您具有非主键的列,在SQL中设置为Is Identity为true且在EF中没有添加此行代码时,也会发生这种情况 [DatabaseGenerated(DatabaseGeneratedOption.Identity)]

谢谢,这是我花了数小时寻找的修复程序。
Vishav Premlall

2

最好的解决方案是使用注解GeneratedValue(strategy = ...),即

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column ...
private int OperationID;

它表示,此列是由数据库使用IDENTITY策略生成的,您无需担心-数据库会做到这一点。



0

如果使用Oracle SQL Developer进行连接,请记住添加/ sqldev:stmt /

/ sqldev:stmt /设置identity_insert表;


显然情况并非如此,问题有一个“ sql-server”标签
DanielV

0

我不确定“插入表”的用途是什么,但是如果您只是想插入一些值,请尝试:

Insert Into [tablename] (OpDescription,FilterID)
values ('Hierachy Update',1);

我收到了相同的错误消息,但我认为这应该可行。只要ID是主键,ID就会自动自动递增。



0

请注意,如果要使用来关闭每一行;,则该SET IDENTITY_INSERT mytable ON命令将不适用于以下行。


像这样的查询

SET IDENTITY_INSERT mytable ON;
INSERT INTO mytable (VoucherID, name) VALUES (1, 'Cole');

给出错误
Cannot insert explicit value for identity column in table 'mytable' when IDENTITY_INSERT is set to OFF.

但是这样的查询将起作用:

SET IDENTITY_INSERT mytable ON
INSERT INTO mytable (VoucherID, name) VALUES (1, 'Cole')
SET IDENTITY_INSERT mytable OFF;

似乎该SET IDENTITY_INSERT命令仅适用于事务,并且;表示事务结束。


-1

如果使用接口并以通用方式实现savechanges的方法,则使用非类型化DBContext或DBSet会引起问题

如果是这种情况,我建议例如强类型化DBContex

MyDBContext.MyEntity.Add(mynewObject)

然后.Savechanges会工作


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.