IDENTITY_INSERT KAPALI olarak ayarlandığında 'tablo' tablosuna kimlik sütunu için açık değer eklenemiyor


361

Aşağıdaki komut dosyasını yürüttüğümde aşağıdaki hata var. Hata nedir ve nasıl çözülebilir?

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

Hata:

Sunucu: Msg 544, Seviye 16, Durum 1, Hat 1

IDENTITY_INSERT KAPALI olarak ayarlandığında 'tablo' tablosuna kimlik sütunu için açık değer eklenemiyor.



2
@HimanshuAhuja Bu soru (1334012) 10 yaşında, sadece sizin bağladığınız 1. Bir şey varsa, o zaman daha yeni bir kopyadır. Ancak yakından baktığınızda farklılık göstereceksiniz (daha yenisi IDENTITY_INSERT değerini ON olarak belirtir). Lütfen bayrağınızı / yorumunuzu silin.
jasie

@jasie bu bayrağı gönderirken hatırlamıyorum gibi yapacak
Himanshu Ahuja

Yanıtlar:


467

Bunun OperationIdbir kimlik sütunu olduğu için değerler ekliyorsunuz .

Kendi kimlik değerlerinizi belirleyebilmeniz için tablodaki kimlik eklentisini açabilirsiniz.

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 tam - açık uçlar izin seçeneğini açın AÇIK , ardından ek ardından seçenek çevirmek KAPALI tekrar
Marc_s

13
Değerinizi gerçekten kimlik sütununa eklemek istiyorsanız, bu sizin cevabınızdır, ancak öte yandan, birisi sütunu ekleme sırasında kendi başına artırılacak şekilde ayarlamıştır. Bu durumda, tablo bir sonraki boş numarayı takip eder ve OperationID'yi kendiniz oluşturmanız gerekmez. Yeni kimlik SELECT SCOPE_IDENTITY () tarafından getirilebilir.
Hakan Winther

15
Tehlikeli uygulama, neden kötü bir fikir olduğunu söyleyen uyarılar olmadan kullanmanızı önermeyin. Çok zayıf cevap.
HLGEM

7
iyi cevap, ama ne yaptığınızı bildiğinizden emin olun. Benim için yabancı anahtarların farklı tablolar üzerinde eşleşmesi gereken verileri içeren bir veritabanı tohumlamak yararlıdır
Berty

2
@UlyssesAlves: Bu seçenek veritabanı genelinde yalnızca tek bir tablo için açılabilir - bu nedenle bir tablo için açık bırakırsanız, başka bir tablo için kullanamazsınız. Ayrıca: bırakılması gereken bir seçenek değil - varsayılan olarak, SQL Server'ın kimlik değerlerini işlemesine izin vermelisiniz - bu sadece çok özel durumlar için son çare ölçüsü olarak tasarlanmıştır - açık veya kapalı bırakmak için genel amaçlı bir seçenek değil boş zamanlarınız ...
marc_s

61

otomatik olarak oluşturulacağından İşlemKimliği'ne değer koymayın. bunu dene:

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

5
otomatik olarak oluşturulan OperationID
shaijut 16:15

46

Basitçe SQL sunucusunda bu hatayı alıyorsanız, bu sorguyu çalıştırın.

SET IDENTITY_INSERT tableName ON

Bu yalnızca tek bir veritabanı tablosu çalışıyor, örneğin tablo adı öğrenci ise sorgu aşağıdaki gibi görünecektir SET IDENTITY_INSERT student ON

Web uygulamanızda bu hatayı alıyorsanız veya varlık çerçevesini kullanıyorsanız, önce bu sorguyu SQL sunucusunda çalıştırın ve varlık modelinizi.edmx file güncelleyin ( ) ve projenizi oluşturun ve bu hata çözülecektir


EF ile MVC web uygulamamda durum buydu ve modeli sadece .edmx'den sildim ve yeniden ekledim (Veritabanından Sağ Tıkla Güncelleme Modeli) ve daha sonra benim için çalışan projeyi temizleyip yeniden oluşturdum. Umang Patwa
Ishwor Khanal

42

IDENTITY_INSERT ayarını AÇIK yapmak konusunda çok dikkatli olun. Veritabanı bakım modunda değilse ve tek kullanıcı olarak ayarlanmadığı sürece bu kötü bir uygulamadır. Bu yalnızca eklentinizi değil, aynı zamanda tabloya erişmeye çalışan başkalarını da etkiler.

Neden bir kimlik alanına değer katmaya çalışıyorsunuz?


5
Ne şekilde etkiler? Bu, tablonun bir özelliği değil, oturum düzeyinde bir seçenektir.
Martin Smith

5
İlişkileri korumak istediğiniz iki veritabanı arasında bir defalık veri senkronizasyonu. Örneğin, ürün
şememi

1
@NSjonas, bu set Identity _insert table1 ON'un iyi bir kullanımı olacaktır. Basit bir ek ile yapılması gereken ve kimliğin oluşturulmasına izin veren uygulamadan bir şey yapmak için bunu kullanmak isteyen insanları gördüm.
HLGEM

2
Soru "Bunun ne olduğunu ve nasıl çözülebileceğini belirtebilir misiniz?" Sorusudur. Cevabınız, sorunu ele alan uygun bir cevap yerine bir uyarı ve başka bir soru getiren bir yorumdur.
Kalite Katalizörü

evet birincil anahtara değer girmeyin.
doflamingo

22

Temelde kayıtları hatasız olarak eklemenin 2 farklı yolu vardır:

1) IDENTITY_INSERT KAPALI olarak ayarlandığında. BİRİNCİL ANAHTAR "ID" OLMAMALIDIR

2) IDENTITY_INSERT AÇIK olarak ayarlandığında. BİRİNCİL ANAHTAR "ID" OLMALIDIR

IDENTITY PRIMARY KEY ile oluşturulan aynı Tablodaki aşağıdaki örneğe göre:

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

1) İlk örnekte, IDENTITY_INSERT KAPALI olduğunda hata almadan tabloya yeni kayıtlar ekleyebilirsiniz. PRIMARY KEY "ID" Mevcut olmamalıdır "INSERT INTO" Tablolara ve benzersiz bir kimlik değeri otomatik olarak eklenecek: . Bu durumda kimlik INSERT'te varsa, "Tablodaki tanımlama sütunu için açık değer eklenemez ..." hatasını alırsınız.

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

TABLO ÇIKIŞI [dbo]. [Kişiler]:

ID    LastName   FirstName
1     DOE        Jane
2     BROWN      JOE

2) İkinci örnekte, IDENTITY_INSERT AÇIK olduğunda hata almadan tabloya yeni kayıtlar ekleyebilirsiniz. PRİMER ANAHTAR "ID" , ID değeri mevcut olmadığı sürece "INSERT INTO" Deyimlerinden SUNULMALIDIR: Bu durumda ID INSERT'de mevcut DEĞİLSE, "Açık değer kimlik sütun tablosu için belirtildi ... "

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'); 

TABLO ÇIKIŞI [dbo]. [Kişiler]:

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

2
Artı aslında bayrağın nasıl çalıştığını açıklamak için.
John

20

Bu tabloya DatabaseGeneratedilişkin varlığınıza, kimlik ekinin ayarlandığı sütunun üstüne niteliği ekleyin :

Misal:

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

Doğru, ama gerçekten EF için bir cevap istedim :-) Yine de, EF'i hiç kullanmamış, hatta belki de karşılaşmamış olabilecek OP için uygun değil.
Auspex

Her durumda, cevap yanlış. Varlığım zaten belirtilmiş DatabaseGeneratedOption.Identityve hala hatayı alıyorum. Bu benim hatam, onları web sayfamda birbirinden ayırmak için yeni satırlara sahte kimlikler koyuyorum ve umarım önce onları boş bırakmayı insertyeterlidir.
Auspex

13

Bu ifadeyi örneğin tablo adınız Okul ise kullanabilirsiniz . Eklemeden önce identity_insert'in ON olarak ayarlandığından emin olun ve ekleme işleminden sonra identity_insert'i KAPALI konuma getirin

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

1
Komutun bir açıklamasını, neden işe yaradığını ve ne gibi bir etkisi olduğunu açıklamak için cevabınızı biraz genişletebilir misiniz?
gareththegeek

@gareththegeek evet onun veri eklemek için yapmak için emin olmak gerekir kimlik sütun içindir.

6

SQL Server'ınızı güncellemek için liquibase kullanıyorsanız, büyük olasılıkla autoIncrement alanına bir kayıt anahtarı eklemeye çalışıyorsunuzdur. Sütunu eklentiden kaldırarak komut dosyanızın çalışması gerekir.

<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

Sorgunuzda otomatik olarak artırıldığı için orada olmaması gereken, önceden belirtilen OperationId var

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

yani sorgunuz

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

3

Başka bir durum, Birincil Anahtarın sınıflarınızla aynı ad olup olmadığını kontrol etmektir; burada tek fark, birincil anahtarınızın kendisine bir 'ID' eklenmiş olmasıdır veya birincil anahtarlarda, anahtarın sınıfı adlandırılır.


2
  1. Bu, SQL'de Kimlik Oldu doğru değerine ayarlanmamış bir (Birincil anahtar) sütununuz varsa ve ekleme sırasında bunun açık değerini iletmediğinizde oluşur. İlk satırı alacaktır, daha sonra ikinci satırı ekleyemezsiniz, hata açılır. Bu, kod satırını [DatabaseGenerated(DatabaseGeneratedOption.Identity)]PrimaryKey sütununuza ekleyerek düzeltilebilir ve int türünde bir veri türüne ayarlandığından emin olabilirsiniz . Sütun birincil anahtarsa ​​ve SQL'de IsIDentity olarak true olarak ayarlanmışsa, bu kod satırına gerek yoktur[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
  2. Bu ayrıca, u birincil anahtar olmayan bir sütuna sahip olduğunuzda, SQL'de Kimlik Kimliği true olarak ayarlandığında ve EF'inizde bu kod satırını eklemediğinizde oluşur [DatabaseGenerated(DatabaseGeneratedOption.Identity)]

Teşekkürler bu düzeltme iv saatlerce bakarak oldu.
Vishav Premlall

2

En iyi çözüm ek açıklama kullanmaktır GeneratedValue(strategy = ...), yani

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

diyor ki, bu sütun IDENTITY stratejisini kullanarak veritabanı tarafından üretiliyor ve ilgilenmenize gerek yok - veritabanı bunu yapacak.


1

Sequelize-typescript npm ile bir sql-server kullanırken bu sorunu yaşıyorsanız @AutoIncrement, kimlik sütununa eklediğinizden emin olun :

  @PrimaryKey
  @AutoIncrement
  @Column
  id!: number;

0

Bağlanmak için Oracle SQL Developer kullanıyorsanız / sqldev: stmt eklemeyi unutmayın /

/ sqldev: stmt / set identity_insert TABLO açık;


Açıkçası bu böyle değil, sorunun bir "sql-server" etiketi var
DanielV

0

"Tablo Ekle" kullanımının ne olduğundan emin değilim, ama sadece bazı değerleri eklemeye çalışıyorsanız deneyin:

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

Ben aynı hata mesajı geldi, ama bence bu işe yarayacak. Kimlik, birincil anahtar olduğu sürece otomatik olarak artmalıdır.


0

Veritabanına her şey eklemek istediğimde yeni bir nesne oluşturarak bu sorunu çözdüm.


0

Her satırı ile kapatıyorsanız ;, SET IDENTITY_INSERT mytable ONkomutun aşağıdaki satırlar için geçerli olmayacağını unutmayın.

yani
bir sorgu

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

Hata verir
Cannot insert explicit value for identity column in table 'mytable' when IDENTITY_INSERT is set to OFF.

Ancak böyle bir sorgu işe yarayacaktır:

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

SET IDENTITY_INSERTKomutun yalnızca bir işlem için ;tutulduğu ve işlemin sonunu belirleyeceği anlaşılıyor .


-1

Arabirim kullanıyorsanız ve genel bir yöntemle koruma mekanizmaları kullanırsanız, yazılmamış DBContext veya DBSet kullanımından kaynaklanan sorun

Bu durumda, örneğin güçlü yazılan DBContex'i öneriyorum

MyDBContext.MyEntity.Add(mynewObject)

o .Savechangeszaman çalışacak


Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.