Bagaimana cara menghidupkan dan mematikan IDENTITY_INSERT menggunakan SQL Server 2008?

461

Mengapa saya mendapatkan kesalahan saat memasukkan ketika IDENTITY_INSERTdiatur ke OFF?

Bagaimana cara mengaktifkannya dengan benar di SQL Server 2008? Apakah dengan menggunakan SQL Server Management Studio?

Saya telah menjalankan kueri ini:

SET IDENTITY_INSERT Database. dbo. Baskets ON

Kemudian saya mendapatkan pesan kembali di konsol bahwa Perintah berhasil diselesaikan. Namun ketika saya menjalankan aplikasi, itu masih memberi saya kesalahan seperti di bawah ini:

Cannot insert explicit value for identity column in table 'Baskets' when 
IDENTITY_INSERT is set to OFF.
Pemula
sumber
Harap rentangkan pertanyaan ini sehingga kami dapat memahami apa yang Anda coba lakukan. Pernyataan apa yang Anda jalankan ketika Anda menemukan kesalahan ini, dan apa teks sebenarnya dari pesan kesalahan itu?
Matt Gibson
Meskipun Anda mengajukan pertanyaan lain, Anda harus menerima jawaban di sini: kami menjawab apa yang Anda tanyakan .
gbn
8
Saya merasa ngeri ketika seseorang mencoba mengirim nilai identitas dari suatu aplikasi. Ini bukan sesuatu yang harus Anda lakukan kecuali untuk migrasi data yang jarang terjadi. Jika Anda melakukan ini cukup teratur untuk menjalankannya dari aplikasi, maka Anda mungkin perlu mengunjungi kembali desain tabel Anda.
HLGEM
Saya menggunakan ini dalam cadangan skrip SQL saya. Selama pemulihan ini izinkan saya memuat data ke tabel Autoincremented dengan nilai asli. Cadangan skrip memungkinkan saya untuk menurunkan versi database SQL. Realisasi Management Studio atas cadangan Skrip membuat skrip yang tidak dapat dibongkar jika saya menyimpan data biner dalam bidang teks.
Jettero

Jawaban:

771

Melalui SQL sesuai MSDN

SET IDENTITY_INSERT sometableWithIdentity ON

INSERT INTO sometableWithIdentity 
    (IdentityColumn, col2, col3, ...)
VALUES 
    (AnIdentityValue, col2value, col3value, ...)

SET IDENTITY_INSERT sometableWithIdentity OFF

Pesan kesalahan lengkap memberitahu Anda persis apa yang salah ...

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

gbn
sumber
@ Pemula: Anda, karenanya kesalahan. Bagaimana kami tahu bahwa Anda tidak ingin memasukkan nilai? Kami hanya memiliki pesan kesalahan
gbn
3
Kesalahan berasal dari aplikasi saya ketika saya melakukan DB.SaveChanges ();
Pemula
5
Tidak, cukup berhenti mengirim nilai untuk kolom identitas. Atau atur jika Anda ingin di aplikasi Anda jika Anda ingin mengirim nilai ..... tapi lalu mengapa kolom dengan properti identitas diatur untuk menghasilkan nilai? Kami tidak dapat memutuskan untuk Anda
gbn
22
@ Pemula: Pengaturan ini hanya berlaku di sesi saat ini (tidak ada yang cukup menunjukkan hal itu untuk pertanyaan ini), jadi aplikasi Anda harus mengaktifkannya agar aplikasi dapat melakukan sisipan tersebut (dan mungkin yang terbaik adalah segera mengaktifkannya) matikan lagi ketika sisipan tersebut diakhiri, seperti acara gbn). Bagaimana Anda memasukkan nilai pada kolom identitas tanpa menyadarinya tidak jelas, tetapi mungkin versi SQL Server yang lebih lama akan memasukkannya secara implisit dengan semua kolom ketika kolom penyisipan eksplisit tidak ditentukan (?) Seperti yang Ismael sarankan.
Rob Parker
2
@ Rob, saya pikir Anda memiliki poin dan saya pribadi gagal meninjau kode pada setiap kode yang tidak disisipkan tanpa menentukan kolom. Selain waktu yang terbuang karena kesalahan, ini adalah praktik yang berisiko dan Anda dapat berakhir dengan masalah integritas data yang serius jika data kolom tidak cocok dengan benar.
HLGEM
59

Saya punya masalah di mana itu tidak memungkinkan saya untuk memasukkannya bahkan setelah mengatur IDENTITY_INSERT ON.

Masalahnya adalah bahwa saya tidak menentukan nama kolom dan untuk beberapa alasan tidak menyukainya.

INSERT INTO tbl Values(vals)

Jadi pada dasarnya lakukan nilai INSERT INTO tbl (cols) penuh (vals)

Ismael
sumber
6
jangan bertanya di panel jawaban.
Duk
4
ini persis apa yang saya inginkan, untuk menentukan daftar kolom (kedua kolom di atas meja, bla)
Maslow
36

Impor: Anda harus menulis kolom dalam INSERTpernyataan

INSERT INTO TABLE
SELECT * FROM    

Tidak benar.

Insert into Table(Field1,...)
Select (Field1,...) from TABLE

Benar

R.Alonso
sumber
2
Terima kasih, itu sangat membantu
José Romero
1
Jika Anda memiliki kolom yang identik di kedua tabel, Anda dapat melakukannya tanpa mencantumkan kolom di pilih (Field1 ..) seperti ini .... Masukkan ke dalam Tabel (Field1, ...) Pilih * dari TABEL ... dan jika Anda memiliki Bidang identitas yang akan disisipkan pertama kali ** SET IDENTITY_INSERT Table_name ON
user3590235
@ user3590235 Itu adalah asumsi berisiko untuk dibuat, bahwa daftar kolom identik. Di luar kueri pengguna manual, jangan pernah lakukan itu, karena saya jamin Anda akan memecah PROD suatu hari ketika orang lain memodifikasi definisi tabel tanpa memperbarui referensi Anda.
Elaskanator
5

Saya tahu ini adalah utas yang lebih tua tetapi saya baru saja menabrak ini. Jika pengguna mencoba menjalankan sisipan pada kolom Identity setelah beberapa sesi lainnya Set IDENTITY_INSERT ON, maka ia terikat untuk mendapatkan kesalahan di atas.

Mengatur nilai Sisipkan Identitas dan perintah Sisipkan DML berikutnya harus dijalankan oleh sesi yang sama.

Di sini @Beginner sedang mengatur Identity Insert ON secara terpisah dan kemudian menjalankan sisipan dari aplikasinya. Itu sebabnya dia mendapat Kesalahan di bawah ini:

Cannot insert explicit value for identity column in table 'Baskets' when 
IDENTITY_INSERT is set to OFF.
OK
sumber
0

Ini kemungkinan ketika Anda memiliki bidang KUNCI UTAMA dan Anda memasukkan nilai yang menduplikasi atau Anda memiliki flag INSERT_IDENTITY diatur ke pada

seanyp20001
sumber
0

Tampaknya perlu untuk meletakkan SET IDENTITY_INSERT Database.dbo.Baskets ON;sebelum setiap INSERTbatch pengiriman SQL .

Anda dapat mengirim beberapa INSERT ... VALUES ...perintah dimulai dengan satu SET IDENTITY_INSERT ... ON;string di awal. Hanya saja, jangan menempatkan pemisah batch antara.

Saya tidak tahu mengapa SET IDENTITY_INSERT ... ONberhenti bekerja setelah blok pengiriman (misalnya: .ExecuteNonQuery()dalam C #). Saya harus meletakkan SET IDENTITY_INSERT ... ON;lagi di awal string perintah SQL berikutnya.

Jettero
sumber
mungkin ini menjawab pertanyaan Anda: stackoverflow.com/questions/5791941/…
Demetris Leptos
0

Opsi lain adalah di mana Anda memiliki tabel seperti 'ketik' atau 'status', misalnya, OrderStatus, di mana Anda selalu ingin mengontrol nilai Id, membuat kolom Id (Kunci Utama) tanpa menjadikannya kolom Identity adalah tempat pertama.

Robert Brooker
sumber
-1

Anda perlu menambahkan perintah 'go' setelah Anda mengatur memasukkan identitas. Contoh:

SET IDENTITY_INSERT sometableWithIdentity ON
go

INSERT sometableWithIdentity (IdentityColumn, col2, col3, ...)
VALUES (AnIdentityValue, col2value, col3value, ...)

SET IDENTITY_INSERT sometableWithIdentity OFF
go
Bruce
sumber
5
Pertanyaan ini berumur empat tahun dan memiliki jawaban yang diterima. Jawaban Anda menduplikasi jawaban yang diterima
Ghost
13
Yah, bukan duplikasi yang tepat - dia memang menyertakan perintah "go" ...;)
RoastBeast