簡體   English   中英

當 IDENTITY_INSERT 設置為 OFF 時,無法在表“table”中為標識列插入顯式值

[英]Cannot insert explicit value for identity column in table 'table' when IDENTITY_INSERT is set to OFF

執行以下腳本時出現以下錯誤。 錯誤是什么,如何解決?

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

錯誤:

服務器:消息 544,16 級,State 1,第 1 行

當 IDENTITY_INSERT 設置為 OFF 時,無法在表“table”中為標識列插入顯式值。

您正在為作為標識列<\/strong>的OperationId<\/code>插入值。

您可以像這樣在表上打開身份插入,以便您可以指定自己的身份值。

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 

不要為 OperationID 賦值,因為它會自動生成。 試試這個:

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

簡單地說,如果您在 SQL 服務器上收到此錯誤,則運行此查詢 -

<\/blockquote>

這僅適用於單個數據庫表,<\/strong>例如,如果表名為student<\/code> ,則查詢如下所示:

 
     
如果您在 Web 應用程序或使用實體框架時遇到此錯誤,則首先在 SQL 服務器上運行此查詢並更新您的實體模型( .edmx file<\/code> )<\/strong>並構建您的項目<\/strong>,此錯誤將得到解決

<\/blockquote>"

將 IDENTITY_INSERT 設置為 ON 時要非常小心。 除非數據庫處於維護模式並設置為單用戶,否則這是一種不好的做法。 這不僅會影響您的插入,還會影響其他任何試圖訪問該表的人。

您為什么要嘗試將值放入身份字段?

在該表的實體中,在設置了標識插入的列上方添加DatabaseGenerated<\/code>屬性:

例子:

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

基本上有兩種不同的方式來插入記錄而不會出錯:

1) 當 IDENTITY_INSERT 設置為 OFF 時。 主鍵“ID”不得存在<\/strong>

2) 當 IDENTITY_INSERT 設置為 ON 時。 必須存在主鍵“ID”<\/strong>

根據使用 IDENTITY PRIMARY KEY 創建的同一表中的以下示例:

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

例如,如果您的表名是School<\/strong> ,您可以簡單地使用此語句。 在插入之前確保 identity_insert 設置為ON<\/strong>並在插入查詢之后將 identity_insert 設置為OFF<\/strong>

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

請注意,如果您用;關閉每一行 SET IDENTITY_INSERT mytable ON命令將不適用於以下行。

IE
像這樣的查詢

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命令僅適用於事務,而; 將表示交易的結束。

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

每個人都在評論 SQL,但 EntityFramework 發生了什么? 我花了整篇文章閱讀,沒有人解決 EF。 所以幾天后找到了解決方案:EF Core 在創建模型的上下文中有這樣的指令: modelBuilder.Entity<Cliente>(entity => { entity.Property(e => e.Id).ValueGeneratedNever();<\/code>

這也會產生錯誤,解決方案:您必須通過 ValueGeneratedOnAdd() 及其作品進行更改!

您的查詢中有預先提到的 OperationId,它不應該存在,因為它是自動遞增的

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

另一種情況是檢查主鍵是否與您的類同名<\/em>,唯一的區別是您的主鍵附加了一個“ID”,或者在與如何使用無關的主鍵上指定 [Key]類被命名。

"

  1. 當您有一個(主鍵)列未在 SQL 中將 Is Identity 設置為 true 並且您在插入期間未傳遞其顯式值時,就會發生這種情況。 它將占用第一行,然后您將無法插入第二行,將彈出錯誤。 這可以通過在 PrimaryKey 列中添加這行代碼[DatabaseGenerated(DatabaseGeneratedOption.Identity)]<\/code>來糾正,並確保將其設置為數據類型int<\/strong> 。 如果該列是主鍵並且在 SQL 中將 IsIDentity 設置為 true,則不需要這行代碼[DatabaseGenerated(DatabaseGeneratedOption.Identity)]<\/code><\/li>
  2. 當你有一個不是主鍵的列,在 SQL 中設置為 Is Identity 為 true,並且在你的 EF 中你沒有添加這行代碼[DatabaseGenerated(DatabaseGeneratedOption.Identity)]<\/code><\/li><\/ol>"

最好的解決方案是使用注解GeneratedValue(strategy = ...)<\/code> ,即

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

如果您在使用帶有 sequelize-typescript npm 的 sql-server 時遇到此問題,請確保將@AutoIncrement<\/code>添加到 ID 列:

  @PrimaryKey
  @AutoIncrement
  @Column
  id!: number;

在我的情況下,我在我的模型構建器的上下文中設置了另一個屬性作為鍵。

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

第一件事首先...

您首先需要知道為什么會出現錯誤。

讓我們看一個 JSON 數據的簡單 HttpPost,如下所示:

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

如果您在連接到 SQLServer 或任何其他數據庫服務器時使用實體框架核心生成數據庫,則數據庫會自動負責更新和自動生成標識列的鍵/唯一標識符,在大多數情況下是一個 integer 值自動增量。

為了使用內置約定安全地發布您的數據,讓您處於更安全的狀態,只需從您要發送到數據庫的數據中刪除 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

我希望您在應用程序中更多地遵守約定而不是配置。 知道如何使用已經證明的標准和慣例來做事,將為您節省大量的工作時間。

而如果你使用Oracle SQL Developer連接,記得添加\/ sqldev:stmt<\/em> \/

\/ sqldev:stmt<\/em> \/set identity_insert TABLE on;

我不確定“插入表”的用途是什么,但如果您只是想插入一些值,請嘗試:

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

每次我想向數據庫添加任何內容時,我都通過創建一個新對象來解決這個問題。

"

在我的案例中,我插入的字符多於表中定義的字符。

在 My Table 中,列是用nvarchar(3)<\/code>定義的,我傳遞了超過 3 個字符<\/em>,並且出現了相同的ERROR<\/code>消息。

它沒有答案,但在某些情況下可能是類似的問題

我正在使用 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
         }///.......

使用帶有這樣的模型的實體框架遇到了同樣的問題(我簡化了原始代碼):

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

EF Core 5,在我的情況下,將“Id”屬性顯式設置為默認值解決了這個問題:

public class PurchaseOrder
    {

        public int Id { get; set; }
        public string FileName { get; set; }
        public string FilePath { get; set; }
        ...
    }
  1. 首先轉到所需的表名<\/li><\/ol>

    第 2 步 -> 右鍵單擊​​表名

    第 3 步 --> 選擇設計

    第 4 步 --> 點擊列名

    步驟 5) 轉到列屬性,然后將No<\/strong>設置為Identity Specification<\/strong>

    [注意:<\/strong>插入顯式值后,如果您願意,您可以恢復為身份規范,然后再次生成該值]

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

    步驟1) 在此處輸入圖像描述<\/a> 第2步)

即使一切正確,如果 Identity 列的數據類型不是 int 或 long,也會出現此錯誤。 我的身份列是十進制的,盡管我只保存 int 值(我的錯)。 更改數據庫和底層模型中的數據類型為我解決了這個問題。

"

在 [HttpPost] 方法上放置斷點並檢查傳遞給 Id 屬性的值。 如果它不是零,則將發生此錯誤。

在我的例子中,問題是,當我嘗試更新記錄時,我自己從代碼中指定了自動增量 ID。 從新記錄創建中刪除 ID 屬性后,一切正常。

為該字段設置identity increment時,不能在 OperationID 列中插入數據。

在此處輸入圖像描述

不要在此字段中輸入值,它將自動設置。

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

如果您使用接口並以通用方式實現 savechanges 方法,則使用非類型化 DBContext 或 DBSet 引發的問題

如果這是你的情況,我建議例如強類型 DBContex

MyDBContext.MyEntity.Add(mynewObject)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM