Tidak dapat memasukkan nilai eksplisit untuk kolom identitas dalam tabel 'tabel' ketika IDENTITY_INSERT diatur ke OFF

361

Saya memiliki kesalahan di bawah ini ketika saya menjalankan skrip berikut. Apa kesalahannya, dan bagaimana cara mengatasinya?

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

Kesalahan:

Server: Msg 544, Level 16, State 1, Line 1

Tidak dapat memasukkan nilai eksplisit untuk kolom identitas dalam tabel 'tabel' ketika IDENTITY_INSERT diatur ke OFF.

martin clayton
sumber
2
@HimanshuAhuja Pertanyaan ini (1334012) berumur 10 tahun, yang Anda tautkan hanya 1. Jika ada, maka yang lebih baru adalah duplikat. Tetapi jika dilihat lebih dekat Anda akan berbeda (yang lebih baru menetapkan IDENTITY_INSERT sebagai ON). Hapus bendera / komentar Anda.
jasie
@ jasie akan melakukan itu karena saya tidak ingat ketika saya telah memposting bendera ini
Himanshu Ahuja

Jawaban:

467

Anda memasukkan nilai untuk OperationIditu adalah kolom identitas.

Anda dapat mengaktifkan sisipan identitas pada tabel seperti ini sehingga Anda dapat menentukan nilai identitas Anda sendiri.

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 
pjp
sumber
14
1 persis - mengubah pilihan untuk memungkinkan sisipan eksplisit ON , kemudian insert, kemudian hidupkan opsi OFF lagi
marc_s
13
Jika Anda benar-benar ingin menambahkan nilai Anda ke kolom identitas, ini adalah jawaban Anda, tetapi di sisi lain, seseorang telah menetapkan kolom yang akan bertambah dengan sendirinya di sisipkan. Dalam hal ini tabel akan melacak nomor gratis berikutnya, dan Anda tidak perlu membuat OperationID sendiri. Id baru dapat diambil oleh SELECT SCOPE_IDENTITY ().
Hakan Winther
15
Latihan berbahaya, jangan rekomendasikan menggunakannya tanpa peringatan yang mengatakan mengapa itu adalah ide yang buruk. Jawaban yang sangat buruk.
HLGEM
7
jawaban yang bagus, tetapi pastikan Anda tahu apa yang Anda lakukan. Bagi saya, berguna untuk menyemai basis data dengan data di mana kunci asing harus cocok dengan tabel yang berbeda
Berty
2
@UlyssesAlves: opsi ini hanya bisa dihidupkan untuk satu tabel di seluruh basis data - jadi jika Anda membiarkannya untuk satu tabel, Anda tidak akan pernah bisa menggunakannya untuk tabel lain. Juga: ini bukan opsi yang harus dibiarkan aktif - secara default, Anda harus membiarkan SQL Server menangani nilai identitas - ini hanya dimaksudkan sebagai langkah terakhir untuk kasus-kasus yang sangat spesifik - bukan opsi tujuan umum untuk membiarkan atau menonaktifkan di liburan Anda ...
marc_s
61

jangan berikan nilai pada OperationID karena akan dihasilkan secara otomatis. coba ini:

Insert table(OpDescription,FilterID) values ('Hierachy Update',1)
Wael Dalloul
sumber
5
ini adalah jawaban yang benar jika Anda ingin OperationID dibuat secara otomatis
shaijut
46

Cukup Jika Anda mendapatkan kesalahan ini pada SQL server kemudian jalankan kueri ini-

SET IDENTITY_INSERT tableName ON

ini hanya berfungsi satu tabel databse misalnya Jika nama tabel adalah siswa maka kueri terlihat seperti ini SET IDENTITY_INSERT student ON

Jika Anda mendapatkan kesalahan ini di aplikasi web Anda atau Anda menggunakan kerangka entitas kemudian jalankan query ini pada SQL server dan Perbarui model entitas.edmx file Anda ( ) dan bangun proyek Anda dan kesalahan ini akan diselesaikan

Umang Patwa
sumber
Itu adalah kasus di aplikasi web MVC saya dengan EF dan saya baru saja menghapus model dari .edmx dan ditambahkan kembali (Klik kanan Perbarui Model Dari Database) dan bersihkan dan bangun kembali proyek yang kemudian bekerja untuk saya. Terima kasih @Umang Patwa
Ishwor Khanal
42

Berhati-hatilah dalam menetapkan IDENTITY_INSERT ke ON. Ini adalah praktik yang buruk kecuali jika database dalam mode pemeliharaan dan diatur ke satu pengguna. Ini tidak hanya memengaruhi penyisipan Anda, tetapi juga orang lain yang mencoba mengakses tabel.

Mengapa Anda mencoba memasukkan nilai ke bidang identitas?

HLGEM
sumber
5
Mempengaruhi dengan cara apa? Ini adalah opsi tingkat sesi bukan properti tabel.
Martin Smith
5
Sinkronisasi data satu kali antara dua database yang ingin Anda pertahankan hubungan. Sebagai contoh saya menggunakannya untuk menarik skema produk saya dari satu database ke yang lain
NSjonas
1
@NSjonas, itu akan menjadi penggunaan yang baik dari set Identity _insert table1 ON. Saya telah melihat orang yang ingin menggunakan ini untuk melakukan sesuatu dari aplikasi yang harus dilakukan dengan menyisipkan sederhana dan memungkinkan identitas untuk dihasilkan.
HLGEM
2
Pertanyaannya adalah "Bisakah Anda menentukan apa itu dan bagaimana cara mengatasinya?" Jawaban Anda adalah komentar yang menimbulkan peringatan dan pertanyaan lain alih-alih jawaban yang tepat yang mengatasi masalah.
Katalis Berkualitas
ya jangan masukkan nilai pada kunci utama.
doflamingo
22

Pada dasarnya ada 2 cara berbeda untuk menyisipkan catatan tanpa mengalami kesalahan:

1) Ketika IDENTITY_INSERT diatur ke OFF. "ID" KUNCI UTAMA TIDAK HARUS MENJADI PRESENT

2) Ketika IDENTITY_INSERT diatur ON. "ID" KUNCI UTAMA HARUS MENJADI PRESENT

Seperti contoh berikut dari Tabel yang sama yang dibuat dengan KUNCI UTAMA IDENTITAS:

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

1) Dalam contoh pertama, Anda bisa menyisipkan catatan baru ke dalam tabel tanpa mendapatkan kesalahan saat IDENTITY_INSERT MATI. PRIMARY KEY "ID" TIDAK HARUS PRESENT dari "INSERT INTO" Laporan dan nilai ID yang unik akan ditambahkan secara otomatis: . Jika ID ada dari INSERT dalam kasus ini, Anda akan mendapatkan kesalahan "Tidak dapat memasukkan nilai eksplisit untuk kolom identifikasi dalam tabel ..."

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

OUTPUT TABEL [dbo]. [Orang] akan:

ID    LastName   FirstName
1     DOE        Jane
2     BROWN      JOE

2) Dalam contoh kedua, Anda bisa menyisipkan catatan baru ke dalam tabel tanpa mendapatkan kesalahan saat IDENTITY_INSERT dalam posisi ON. PRIMARY KEY "ID" HARUS MENJADI PRESENT dari Pernyataan "INSERT INTO" selama nilai ID belum ada : Jika ID TIDAK hadir dari INSERT dalam hal ini, Anda akan mendapatkan kesalahan "Nilai eksplisit harus ditentukan untuk tabel kolom identitas ... "

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

OUTPUT TABEL [dbo]. [Orang] akan:

ID    LastName   FirstName
1     DOE        Jane
2     BROWN      JOE
3     BLACK      JACK
5     WHITE      JOHN
Spesialis QA
sumber
2
Plus satu untuk benar-benar Menjelaskan cara kerja bendera. Menyelamatkan hariku Superman
John
20

Di entitas Anda untuk tabel itu, tambahkan DatabaseGeneratedatribut di atas kolom yang sisipan identitasnya ditetapkan:

Contoh:

[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int TaskId { get; set; }
pengguna902490
sumber
Ya, benar, tapi saya benar-benar menginginkan jawaban untuk EF :-) Namun, itu tidak sesuai untuk OP yang mungkin tidak pernah menggunakan, atau mungkin bahkan bertemu, EF.
Auspex
Bagaimanapun, jawabannya salah. Entitas saya sudah ditentukan dengan DatabaseGeneratedOption.Identity, dan saya masih mendapatkan kesalahan. Ini kesalahan saya sendiri, saya meletakkan ID-pseudo di baris baru untuk membedakan mereka satu sama lain di halaman web saya, dan saya harap hanya membatalkan mereka sebelum insertcukup.
Auspex
13

Anda cukup menggunakan pernyataan ini misalnya jika nama tabel Anda adalah Sekolah . Sebelum penyisipan, pastikan identity_insert diatur ke AKTIF dan setelah memasukkan kueri, giliran identity_insert OFF

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

sumber
1
Bisakah Anda memperluas jawaban Anda sedikit untuk memasukkan penjelasan tentang perintah, mengapa itu berhasil dan apa efeknya?
gareththegeek
@gareththegeek ya untuk kolom identitas Anda harus memastikan untuk memasukkan data.
6

Jika Anda menggunakan liquibase untuk memperbarui SQL Server Anda, Anda kemungkinan mencoba memasukkan kunci rekaman ke dalam bidang AutoIncrement. Dengan menghapus kolom dari sisipan, skrip Anda harus dijalankan.

<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>
iowatiger08
sumber
4

Ada OperationId yang disebutkan sebelumnya dalam kueri Anda yang seharusnya tidak ada di sana karena secara otomatis ditingkatkan

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

jadi permintaan Anda akan

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

Situasi lain adalah untuk memeriksa bahwa Kunci Utama adalah nama yang sama dengan kelas Anda di mana satu-satunya perbedaan adalah bahwa kunci utama Anda memiliki 'ID' yang ditambahkan atau menentukan [Kunci] pada kunci primer yang tidak terkait dengan bagaimana kelas diberi nama.

salemsky95
sumber
2
  1. Ini terjadi ketika Anda memiliki kolom (kunci utama) yang tidak disetel ke Apakah Identitas menjadi benar dalam SQL dan Anda tidak memberikan nilai eksplisitnya selama memasukkan. Ini akan mengambil baris pertama, maka Anda tidak akan bisa memasukkan baris kedua, kesalahan akan muncul. Ini dapat diperbaiki dengan menambahkan baris kode ini [DatabaseGenerated(DatabaseGeneratedOption.Identity)]di kolom PrimaryKey Anda dan pastikan set ke int tipe data . Jika kolom adalah kunci utama dan disetel ke IsIDentity menjadi true dalam SQL, maka tidak perlu untuk baris kode ini[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
  2. ini juga terjadi ketika Anda memiliki kolom yang bukan kunci utama, dalam SQL yang disetel ke Identity menjadi true, dan di EF Anda Anda tidak menambahkan baris kode ini [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
Siphamandla Hero Ngwenya
sumber
Terima kasih ini adalah perbaikan iv menghabiskan berjam-jam mencari.
Vishav Premlall
2

Solusi terbaik adalah dengan menggunakan anotasi GeneratedValue(strategy = ...), yaitu

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

dikatakan, bahwa kolom ini dihasilkan oleh database menggunakan strategi IDENTITY dan Anda tidak perlu mengurusnya - database akan melakukannya.

Tomasz Dzięcielewski
sumber
1

Jika Anda mengalami masalah ini saat menggunakan sql-server dengan skrip sekuens-npm pastikan untuk menambahkan @AutoIncrementke kolom ID:

  @PrimaryKey
  @AutoIncrement
  @Column
  id!: number;
Kate Kasinskaya
sumber
0

Dan jika Anda menggunakan Oracle SQL Developer untuk terhubung, ingatlah untuk menambahkan / sqldev: stmt /

/ sqldev: stmt / set identity_insert TABEL aktif;

Hao Deng
sumber
Jelas ini bukan masalahnya, pertanyaannya memiliki tag "sql-server"
DanielV
0

Saya tidak yakin apa gunanya "Sisipkan Tabel", tetapi jika Anda hanya mencoba memasukkan beberapa nilai coba:

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

Saya memiliki pesan kesalahan yang sama muncul, tetapi saya pikir ini harus berhasil. ID akan otomatis bertambah secara otomatis selama itu adalah kunci utama.

Matius
sumber
0

Saya memecahkan masalah ini dengan membuat objek baru setiap kali saya ingin menambahkan apa pun ke database.

Naresh Bisht
sumber
0

Perhatikan bahwa jika Anda menutup setiap baris dengan ;, SET IDENTITY_INSERT mytable ONperintah tidak akan berlaku untuk baris berikut.

yaitu
permintaan seperti

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

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

Tetapi kueri seperti ini akan berfungsi:

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

Sepertinya SET IDENTITY_INSERTperintah hanya berlaku untuk transaksi, dan ;akan menandakan akhir transaksi.

cryanbhu
sumber
-1

Masalah yang timbul dari menggunakan DBContext atau DBSet yang tidak diketik jika Anda menggunakan Interface dan mengimplementasikan metode savechanges dengan cara yang umum

Jika ini adalah kasus Anda, saya mengusulkan untuk mengetik DBContex kuat misalnya

MyDBContext.MyEntity.Add(mynewObject)

maka .Savechangesakan bekerja

Mostafa Basha
sumber