Làm cách nào để bật và tắt IDENTITY_INSERT bằng SQL Server 2008?


461

Tại sao tôi gặp lỗi khi chèn khi IDENTITY_INSERTđược đặt thành TẮT?

Làm cách nào để bật nó đúng cách trong SQL Server 2008? Có phải bằng cách sử dụng SQL Server Management Studio?

Tôi đã chạy truy vấn này:

SET IDENTITY_INSERT Database. dbo. Baskets ON

Sau đó, tôi nhận được thông báo trở lại trong bảng điều khiển rằng (các) Lệnh đã hoàn thành thành công. Tuy nhiên, khi tôi chạy ứng dụng, nó vẫn báo lỗi bên dưới:

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

Vui lòng mở rộng câu hỏi này để chúng tôi có thể hiểu những gì bạn đang cố gắng làm. Câu lệnh nào bạn đang chạy khi gặp lỗi này và văn bản thực tế của thông báo lỗi là gì?
Matt Gibson

Mặc dù bạn đã hỏi một câu hỏi khác, bạn nên chấp nhận một câu trả lời ở đây: chúng tôi đã trả lời những gì bạn hỏi .
gbn

8
Tôi có một nỗi kinh hoàng về ý tưởng rằng ai đó đang cố gắng gửi các giá trị nhận dạng từ một ứng dụng. Đây không phải là điều mà bạn nên làm ngoại trừ việc di chuyển dữ liệu không thường xuyên. Nếu bạn đang làm điều này thường xuyên đủ để chạy nó từ một ứng dụng, thì có lẽ bạn cần phải xem lại thiết kế bảng của mình.
HLGEM

Tôi đang sử dụng điều này trong bản sao lưu kịch bản SQL của mình. Trong quá trình khôi phục, hãy để tôi tải dữ liệu vào bảng Autoincremented với các giá trị ban đầu. Bản sao lưu theo kịch bản cho phép tôi hạ cấp cơ sở dữ liệu SQL. Việc thực hiện sao lưu Scripted của Studio quản lý làm cho tập lệnh không tải được nếu tôi lưu trữ dữ liệu nhị phân trong trường văn bản.
Jettero

Câu trả lời:


771

Thông qua SQL theo MSDN

SET IDENTITY_INSERT sometableWithIdentity ON

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

SET IDENTITY_INSERT sometableWithIdentity OFF

Thông báo lỗi hoàn chỉnh cho bạn biết chính xác những gì sai ...

Không thể chèn giá trị rõ ràng cho cột danh tính trong bảng 'somableWithIdentity' khi IDENTITY_INSERT được đặt thành TẮT.


@Beginner: bạn là mặc dù, do đó lỗi. Làm thế nào để chúng tôi biết rằng bạn không muốn chèn giá trị? Chúng tôi chỉ có một thông báo lỗi
gbn

3
Lỗi là từ ứng dụng của tôi khi tôi làm DB.SaveChanges ();
Người mới bắt đầu

5
Không, chỉ cần ngừng gửi một giá trị cho cột danh tính. Hoặc đặt nó nếu bạn muốn trong ứng dụng của mình nếu bạn muốn gửi một giá trị ..... nhưng tại sao lại có một cột với thuộc tính nhận dạng được đặt để tạo giá trị? Chúng tôi không thể quyết định cho bạn
gbn

22
@Beginner: Cài đặt chỉ có thể áp dụng trong phiên hiện tại (không ai chỉ ra câu hỏi này), vì vậy ứng dụng của bạn sẽ phải bật ứng dụng để ứng dụng thực hiện các thao tác chèn đó (và có lẽ tốt nhất là bật ngay nó lại tắt khi các phần chèn như vậy được kết luận, như các chương trình gbn). Cách bạn chèn một giá trị trên cột nhận dạng mà không nhận ra nó không rõ ràng, nhưng có lẽ các phiên bản cũ hơn của SQL Server sẽ bao gồm nó với tất cả các cột khi các cột chèn rõ ràng không được chỉ định (?) Như Ismael đề xuất.
Rob Parker

2
@Rob, tôi nghĩ bạn không biết điểm cá nhân tôi không xem xét mã trên bất kỳ mã nào mà không chèn mà không chỉ định các cột. Ngoài thời gian lãng phí cho một lỗi, đây là một thực tế rủi ro và bạn có thể gặp phải các vấn đề toàn vẹn dữ liệu nghiêm trọng nếu dữ liệu cột không khớp chính xác.
HLGEM

59

Tôi gặp sự cố khi nó không cho phép tôi chèn nó ngay cả sau khi đặt IDENTITY_INSERT ON.

Vấn đề là tôi đã không chỉ định tên cột và vì một số lý do nó không thích nó.

INSERT INTO tbl Values(vals)

Vì vậy, về cơ bản hãy thực hiện đầy đủ các giá trị INSERT INTO tbl (cols) (vals)


6
đừng đặt câu hỏi trong khung trả lời.
Duk

4
đây chính xác là những gì tôi muốn, để chỉ định danh sách cột (cả hai cột trên bàn, blah)
Maslow

36

Nhập: Bạn phải viết các cột trong INSERTcâu lệnh

INSERT INTO TABLE
SELECT * FROM    

Không đúng

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

Đúng


2
Cảm ơn bạn, điều đó rất hữu ích
Jose Romero

1
Nếu bạn có các cột giống hệt nhau trong cả hai bảng, bạn có thể làm mà không liệt kê các cột trong phần chọn (Trường1 ..) như thế này .... Chèn vào Bảng (Trường1, ...) Chọn * từ BẢNG ... và nếu bạn có Trường nhận dạng để chèn đầu tiên làm ** SET IDENTITY_INSERT
Table_name

@ user3590235 Đó là một giả định rủi ro để thực hiện, rằng danh sách cột là giống hệt nhau. Ngoài các truy vấn người dùng thủ công, không bao giờ làm điều đó, bởi vì tôi đảm bảo bạn sẽ phá vỡ một ngày nào đó khi ai đó sửa đổi định nghĩa bảng mà không cập nhật tham chiếu của bạn.
Elaskanator

5

Tôi biết đây là một chủ đề cũ hơn nhưng tôi chỉ va vào đây. Nếu người dùng đang cố chạy chèn trên cột Danh tính sau một số phiên khác Đặt IDENTITY_INSERT ON, thì anh ta bị ràng buộc để nhận lỗi trên.

Đặt giá trị Chèn nhận dạng và các lệnh Chèn DML tiếp theo sẽ được chạy bởi cùng một phiên.

Ở đây @Beginner đã thiết lập riêng biệt Chèn nhận dạng và sau đó chạy các phần chèn từ ứng dụng của mình. Đó là lý do tại sao anh ta nhận được Lỗi dưới đây:

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

0

Điều này có thể xảy ra khi bạn có trường PRIMARY KEY và bạn đang chèn một giá trị đang nhân đôi hoặc bạn có cờ INSERT_IDENTITY được đặt thành bật


0

Có vẻ cần phải đặt SET IDENTITY_INSERT Database.dbo.Baskets ON;trước mỗi INSERTđợt gửi SQL .

Bạn có thể gửi một số INSERT ... VALUES ...lệnh bắt đầu bằng một SET IDENTITY_INSERT ... ON;chuỗi ở đầu. Chỉ cần không đặt bất kỳ phân cách lô giữa.

Tôi không biết tại sao các SET IDENTITY_INSERT ... ONđiểm dừng hoạt động sau khối gửi (ví dụ: .ExecuteNonQuery()trong C #). Tôi đã phải đặt SET IDENTITY_INSERT ... ON;lại ở đầu chuỗi lệnh SQL tiếp theo.


có lẽ điều này trả lời câu hỏi của bạn: stackoverflow.com/questions/5791941/ từ
Demetris Leptos

-1

Bạn cần thêm lệnh 'go' sau khi bạn đặt chèn danh tính. Thí dụ:

SET IDENTITY_INSERT sometableWithIdentity ON
go

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

SET IDENTITY_INSERT sometableWithIdentity OFF
go

5
Câu hỏi này là bốn tuổi và có một câu trả lời được chấp nhận. Câu trả lời của bạn trùng lặp câu trả lời được chấp nhận
Ghost

13
Chà, không phải là một bản sao chính xác - anh ấy đã bao gồm các lệnh "đi" ...;)
RoastBeast
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.