ChatGPT解决这个技术问题 Extra ChatGPT

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

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

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

错误:

服务器:消息 544,级别 16,状态 1,第 1 行当 IDENTITY_INSERT 设置为 OFF 时,无法在表“表”中插入标识列的显式值。


M
Martin Smith

您正在为 身份列的 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 

完全 +1 - 打开选项以允许显式插入,然后插入,然后再次关闭选项
如果您真的想将您的值添加到标识列,这就是您的答案,但另一方面,有人已将该列设置为在插入时自行递增。在这种情况下,该表将跟踪下一个空闲号码,您无需自己生成 OperationID。新 id 可以通过 SELECT SCOPE_IDENTITY() 获取。
很好的答案,但请确保您知道自己在做什么。对我来说,用外键需要在不同表上匹配的数据为数据库播种是很有用的
@marc_s 为什么要再次关闭它?难道不能只设置ON,这样我们每次需要在表上插入记录时就不需要设置ON/OFF吗?
@UlyssesAlves:此选项只能在数据库范围内的单个表中打开 - 因此,如果您将其保留为一个表,您将无法将其用于另一个表。另外:这不是一个应该保留的选项 - 默认情况下,您应该让 SQL Server 处理标识值 - 这仅作为非常特定情况下的最后手段 - 不是在你的休闲...
W
Wael Dalloul

不要为 OperationID 赋值,因为它会自动生成。尝试这个:

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

如果您想自动生成 OperationID,这是正确的答案
O
Oli Folkerd

简单地说,如果您在 SQL 服务器上收到此错误,则运行此查询 -

SET IDENTITY_INSERT tableName ON

这仅适用于单个数据库表 例如,如果表名是 student,则查询如下所示:

SET IDENTITY_INSERT student ON

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


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

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

您为什么要尝试将值放入身份字段?


以什么方式影响?这是一个会话级别的选项,而不是表的属性。
在您想要维护关系的两个数据库之间进行一次数据同步。例如,我用它把我的产品模式从一个数据库拉到另一个数据库
@NSjonas,这将是 set Identity _insert table1 ON 的一个很好的用途。我见过有人想用它在应用程序中做一些事情,这些事情应该通过简单的插入来完成,并允许生成身份。
问题是“您能否具体说明它是什么以及如何解决它?”您的回答是提出警告和另一个问题的评论,而不是解决问题的正确答案。
是的,不要在主键中插入值。
g
glennsl

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

例子:

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

嗯,是的,但我真的很想要 EF 的答案 :-) 不过,这对于可能从未使用过,甚至可能从未遇到过 EF 的 OP 来说并不合适。
无论如何,答案是错误的。我的实体已经用 DatabaseGeneratedOption.Identity 指定,但我仍然收到错误消息。这是我自己的错,我将伪 ID 放在新行中以在我的网页上将它们彼此区分开来,我希望在 insert 足够之前将它们清空。
Q
QA Specialist

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

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].[Persons] 的输出将是:

ID    LastName   FirstName
1     DOE        Jane
2     BROWN      JOE

2) 在第二个示例中,您可以在 IDENTITY_INSERT 为 ON 时向表中插入新记录而不会出错。只要 ID 值不存在,“INSERT INTO”语句中的主键“ID”必须存在:如果在这种情况下 INSERT 中不存在 ID,您将收到错误“显式值必须是为标识列表指定..."

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].[Persons] 的输出将是:

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

加一个用于实际解释标志的工作原理。拯救了我的一天
佚名

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

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

您能否稍微扩展您的答案以包括对该命令的解释,它为什么起作用以及它有什么作用?
@gareththegeek 是的,对于标识列,您必须确保将其插入数据。
c
cryanbhu

请注意,如果您用 ; 关闭每一行,则 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 命令仅适用于事务,而 ; 将表示事务结束。


i
iowatiger08

如果您使用 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>

L
Leniel Maccaferri

每个人都在评论 SQL,但 EntityFramework 发生了什么?我花了整篇文章阅读,没有人解决 EF。所以几天后找到了解决方案:EF Core 在创建模型的上下文中有这样的指令: modelBuilder.Entity<Cliente>(entity => { entity.Property(e => e.Id).ValueGeneratedNever();

这也会产生错误,解决方案:您必须通过 ValueGeneratedOnAdd() 及其作品进行更改!


O
Onkar_M18

您的查询中有预先提到的 OperationId,它不应该存在,因为它是自动递增的

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

所以你的查询将是

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

T
Tomasz Dzięcielewski

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

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

它说,此列是由数据库使用 IDENTITY 策略生成的,您不需要照顾 - 数据库会这样做。


Ω
ΩmegaMan

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


S
Siphamandla Ngwenya

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


谢谢这是我花了几个小时寻找的修复程序。
K
Kate Kasinskaya

如果您在使用带有 sequelize-typescript npm 的 sql-server 时遇到此问题,请确保将 @AutoIncrement 添加到 ID 列:

  @PrimaryKey
  @AutoIncrement
  @Column
  id!: number;

N
Naresh Bisht

每次我想向数据库添加任何内容时,我都通过创建一个新对象来解决这个问题。


u
user3542654

在我的情况下,我在我的模型构建器的上下文中设置了另一个属性作为键。

modelBuilder.Entity<MyTable>().HasKey(t => t.OtherProp);

我必须设置正确的 id

 modelBuilder.Entity<MyTable>().HasKey(t => t.Id);

D
David Charles

EF 核心 3.x

参考 Leniel Maccaferri,我有一个表,其中包含一个名为 ID(原始主键)的自动增量属性和另一个名为 Other_ID(新主键)的属性。最初 ID 是主键,但后来 Other_ID 需要成为新的主键。由于 ID 正在应用程序的其他部分中使用,因此我不能只将其从表中删除。 Leniel Maccaferri 解决方案仅在我添加以下代码段后对我有效:

        entity.HasKey(x => x.Other_ID);
        entity.Property(x => x.ID).ValueGeneratedOnAdd();

下面的完整代码片段(ApplicationDbContext.cs):

  protected override void OnModelCreating(ModelBuilder builder)
  {
        builder.ApplyConfigurationsFromAssembly(Assembly.GetExecutingAssembly());
        base.OnModelCreating(builder);
        builder.Entity<tablename>(entity =>
        {
            entity.HasKey(x => x.Other_ID);
            entity.Property(x => x.ID).ValueGeneratedOnAdd();
            entity.HasAlternateKey(x => new { x.Other_ID, x.ID });                
        });
        
    }

我的桌子和你的完全一样,卡住的是旧的 Id。要修复它,只需将旧的 ID 保留为零 0,DB 将确定是否通用一个新的 id,并且可以在不添加 AlternateKey 的情况下修复错误
H
Hoque MD Zahidul

首先转到所需的表名

第 2 步 -> 右键单击表名

第 3 步 --> 选择设计

第 4 步 --> 点击列名

步骤 5) 转到列属性,然后将 No 设置为 Identity Specification

[注意:插入显式值后,如果您愿意,您可以恢复身份规范,然后再次生成该值]

如果您使用 SQL Server Management Studio,您可以使用以下方法

https://i.stack.imgur.com/P9bK9.png


P
Prashant Gupta

即使一切正确,如果 Identity 列的数据类型不是 int 或 long,也会出现此错误。我的身份列是十进制的,尽管我只保存 int 值(我的错)。更改数据库和底层模型中的数据类型为我解决了这个问题。


O
Okechukwu Ezekiel

第一件事首先...

您首先需要知道为什么会出现错误。

让我们看一个 JSON 数据的简单 HttpPost,如下所示:

{
"conversationID": 1, 
"senderUserID": 1, 
"receiverUserID": 2,
"message": "I fell for the wrong man!",
"created":"2022-02-14T21:18:11.186Z"
}

如果您在连接到 SQLServer 或任何其他数据库服务器时使用实体框架核心生成数据库,则数据库会自动负责更新和自动生成标识列的键/唯一标识符,在大多数情况下,它是一个整数值自动增量。

为了使用内置约定安全地发布您的数据,让您处于更安全的状态,只需从您要发送到数据库的数据中删除 ID 字段,然后让数据库引擎和 ef-core 完成繁重的工作旨在做。

因此,发布数据的正确方法是:

{ 
    "senderUserID": 1, 
    "receiverUserID": 2,
    "message": "I fell for the wrong man!",
    "created":"2022-02-14T21:18:11.186Z"
    }

你会注意到我拿出了 ConversationID。

您可以在此网站上了解有关实体框架的更多信息:https://entityframeworkcore.com

我希望您在应用程序中更多地遵守约定而不是配置。知道如何使用已经证明的标准和惯例来做事,将为您节省大量的工作时间。


H
Hao Deng

而且如果你使用Oracle SQL Developer连接,记得添加/sqldev:stmt/

/sqldev:stmt/ 设置 identity_insert TABLE on;


显然不是这样,问题有一个“sql-server”标签
T
Theresa

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

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

我有同样的错误信息出现,但我认为这应该工作。只要 ID 是主键,它就会自动递增。


W
Wasim

在我的案例中,我插入的字符多于表中定义的字符。

在我的表列中定义了 nvarchar(3),我传递了 超过 3 个字符,同样的 ERROR 消息即将到来。

它没有答案,但在某些情况下可能是类似的问题


B
BerkGarip

我正在使用 asp.net core 5.0,我得到了那个错误。我收到该错误是因为我正在添加另一个数据并触发另一个 .SaveChanges() 方法,如下所示:

 _unitOfWorkVval.RepositoryVariantValue.Create(variantValue);
 int request = HttpContext.Response.StatusCode;
 if (request == 200)
 {
     int tryCatch = _unitOfWorkCVar.Complete();
     if (tryCatch != 0)
     {
         productVariant.CategoryVariantID = variantValue.CategoryVariantID;
         productVariant.ProductID = variantValue.ProductID;
         productVariant.CreatedDate = DateTime.Now;
         _unitOfWorkProductVariant.RepositoryProductVariant.Create(productVariant);
         _unitOfWorkVval.RepositoryVariantValue.Create(variantValue);
         int request2 = HttpContext.Response.StatusCode;
         if(request==200)
         {
             int tryCatch2=_unitOfWorkProductVariant.Complete();//The point where i get that error
         }///.......


A
Andras

使用带有这样的模型的实体框架遇到了同样的问题(我简化了原始代码):

public class Pipeline
{
  public Pipeline()
  {
     Runs = new HashSet<Run>();
  }

  public int Id {get; set;}
  public ICollection<Run> Runs {get;set;}
}

public class Run
{
  public int Id {get; set;}
  public int RequestId {get; set;}
  public Pipeline Pipeline {get;set;}
}

Run 与 Pipeline 具有多对一的关系(一个 Pipeline 可以运行多次)

在我的 RunService 中,我将 DbContex 作为 context 注入。 DbContext 有一个 Runs DbSet。我在 RunService 中实现了这个方法:

public async Task<Run> CreateAndInit(int requestId, int pplId)
{
  Pipeline pipeline = await pipelineService.Get(pplId).FirstOrDefaultAsync().ConfigureAwait(false);
  Run newRun = new Run {RequestId = requestId, Pipeline = pipeline};
  context.Runs.Add(newRun);
  await context.SaveChangesAsync().ConfigureAwait(false); // got exception in this line
  return newRun;
}

当方法执行时,我得到了这个异常:

Exception has occurred: CLR/Microsoft.EntityFrameworkCore.DbUpdateException
Exception thrown: 'Microsoft.EntityFrameworkCore.DbUpdateException' in System.Private.CoreLib.dll: 'An error occurred while updating the entries. See the inner exception for details.'
 Inner exceptions found, see $exception in variables window for more details.
 Innermost exception     Microsoft.Data.SqlClient.SqlException : Cannot insert explicit value for identity column in table 'Pipelines' when IDENTITY_INSERT is set to OFF.

对我来说,解决方案是将对象和关系的创建分开

public async Task<Run> CreateAndInit(int requestId, int pplId)
{
  Pipeline pipeline = await pipelineService.Get(pplId).FirstOrDefaultAsync().ConfigureAwait(false);
  Run newRun = new Run {RequestId = requestId};
  context.Runs.Add(newRun);
  newRun.Pipeline = pipeline; // set the relation separately
  await context.SaveChangesAsync().ConfigureAwait(false); // no exception
  return newRun;
}

c
codearmalik

在 [HttpPost] 方法上放置断点并检查传递给 Id 属性的值。如果它不是零,则将发生此错误。


这没有提供问题的答案。一旦你有足够的reputation,你就可以comment on any post;相反,provide answers that don't require clarification from the asker。 - From Review
A
Al Foиce ѫ

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

如果这是你的情况,我建议例如强类型 DBContex

MyDBContext.MyEntity.Add(mynewObject)

那么 .Savechanges 将起作用


E
Encrypted Drink

只需删除拖入 .dbml 文件的表,然后再次重新拖动它们。然后清洁解决方案>重建解决方案>构建解决方案。

那对我有用。

我没有自己制作表格,我使用的是 VS 和 SSMS,我点击此链接获取 ASP.NET Identity:https://docs.microsoft.com/en-us/aspnet/identity/overview/getting-started/adding-aspnet-identity-to-an-empty-or-existing-web-forms-project