248

Tôi đang cố gắng lấy lại giá trị khóa sau câu lệnh INSERT. Ví dụ: Tôi đã có một bảng có tên thuộc tính và id. id là một giá trị được tạo ra.

    INSERT INTO table (name) VALUES('bob');

Bây giờ tôi muốn lấy lại id trong cùng một bước. Làm thế nào được thực hiện?

Chúng tôi đang sử dụng Microsoft SQL Server 2008.

|
395

Không cần CHỌN riêng ...

INSERT INTO table (name)
OUTPUT Inserted.ID
VALUES('bob');

Điều này cũng hoạt động cho các cột không IDENTITY (chẳng hạn như GUID)

|
154

Sử dụng SCOPE_IDENTITY()để nhận giá trị ID mới

INSERT INTO table (name) VALUES('bob');

SELECT SCOPE_IDENTITY()

http://msdn.microsoft.com/en-us/l Library / ms190315.aspx

|
33
INSERT INTO files (title) VALUES ('whatever'); 
SELECT * FROM files WHERE id = SCOPE_IDENTITY();

Là đặt cược an toàn nhất vì có một vấn đề đã biết với xung đột Khoản OUTPUT trên các bảng có kích hoạt. Làm cho điều này khá không đáng tin vì ngay cả khi bảng của bạn hiện không có bất kỳ trình kích hoạt nào - ai đó thêm một dòng xuống sẽ phá vỡ ứng dụng của bạn. Bom hẹn giờ sắp xếp hành vi.

Xem bài viết msDN để giải thích sâu hơn:

http://bloss.msdn.com/b/sqlprogrammability/archive/2008/07/11/update-with-output-clause-triggers-and-sqlmoreresults.aspx

|
  • 1

    Chỉ khi bạn không thêm SET NOCOUNT ON trong trình kích hoạt. Ngoài ra, hãy xem docs.microsoft.com/en-us/sql/database-engine/configure-windows/ mẹo

    – Lin ShiNu 08:48:25 13/03/2018
  • 1

    đây không phải là một lựa chọn cho môi trường kế thừa của chúng tôi @gbn

    – Dương Gia Hiệp 03:16:00 16/03/2018
  • 1

    @hajikelist Tất cả chúng ta đều có di sản, nhưng nguy cơ kích hoạt OUTPUT gây rối là rất thấp, tất cả những gì nó cần được đặt là không cần thiết. Nếu ai đó đang thêm trình kích hoạt thì họ nên biết cách mã hóa nó (ngụ ý rằng bạn có quyền kiểm soát chủ yếu) hoặc bạn cần đào tạo các nhà phát triển của mình .. Đến một lúc nào đó, bạn sẽ buộc phải di chuyển khi phiên bản SQL đó không còn được hỗ trợ, vì vậy các trình kích hoạt sẽ không gây ra kết quả. Dù thế nào đi nữa, đó không phải là câu trả lời tốt nhất bởi vì nếu bạn đã kích hoạt INSTEAD OF thì SCOPE_IDENTITY có thể không hoạt động ( stackoverflow.com/questions/908257/ Lỗi )

    – Trịnh Kim Thanh 07:35:01 16/03/2018
  • 1

    @gbn - Tôi chỉ muốn tránh những thứ ngớ ngẩn như thế này. Tôi sẽ không nói với tất cả các nhà phát triển của mình, "Đừng quên thêm 'không phá vỡ tuyên bố ứng dụng của tôi' trong mỗi kích hoạt." - bạn có thể giữ nó. Kịch bản "thay thế" là nhiều hơn một trường hợp cạnh imo.

    – Hồ Thái Thanh 17:39:29 16/03/2018
  • 1

    Một câu trả lời an toàn hơn có thể chỉ là để ứng dụng chạy một truy vấn khác một khi nó trả về từ câu hỏi này. Miễn là nó được thực hiện ở mặt sau, hình phạt về hiệu suất nên có giá trị đơn giản trong việc quản lý sự phát triển trong các nhóm người và nó gần với các tiêu chuẩn hơn so với một số tính năng điên rồ với các trường hợp cạnh. Tôi muốn thay vào đó là các trường hợp cạnh nằm trong mã của tôi và tránh chúng trên các nền tảng. chỉ là ý kiến ​​của tôi không có gì lạ lùng :)

    – Trịnh Phước Sơn 14:22:28 21/09/2018
21

Entity Framework thực hiện một cái gì đó tương tự như câu trả lời của gbn:

DECLARE @generated_keys table([Id] uniqueidentifier)

INSERT INTO Customers(FirstName)
OUTPUT inserted.CustomerID INTO @generated_keys
VALUES('bob');

SELECT t.[CustomerID]
FROM @generated_keys AS g 
   JOIN dbo.Customers AS t 
   ON g.Id = t.CustomerID
WHERE @@ROWCOUNT > 0

Các kết quả đầu ra được lưu trữ trong một biến bảng tạm thời, và sau đó được chọn trở lại máy khách. Phải có ý thức về gotcha:

các phần chèn có thể tạo nhiều hơn một hàng, vì vậy biến có thể chứa nhiều hơn một hàng, do đó bạn có thể được trả về nhiều hơn một hàng ID

Tôi không biết tại sao EF lại tham gia vào bảng phù du trở lại bàn thực (trong trường hợp nào hai người sẽ không khớp nhau).

Nhưng đó là những gì EF làm.

SQL Server 2008 hoặc mới hơn. Nếu đó là năm 2005 thì bạn đã hết may mắn.

|
8

@@ IDENTITY Là một hàm hệ thống trả về giá trị nhận dạng được chèn lần cuối.

|
  • 1

    Phải khuyên bạn không bao giờ sử dụng @@ IDENTITY - nó không chính xác (quá rộng) ít an toàn cho chủ đề hơn - vui lòng xem câu trả lời của @ Curt về SCOPE_IDENTITY ().

    – Lin ShiNu 23:37:16 16/04/2018
5

Sau khi thực hiện thao tác chèn vào bảng có cột nhận dạng, bạn có thể tham khảo @@ IDENTITY để nhận giá trị: http://msdn.microsoft.com/en-us/l Library / aa933167% 28v = sql.80% 29.aspx

|
4

Bạn có thể sử dụng scope_identity để chọn ID của hàng bạn vừa chèn vào một biến sau đó chỉ cần chọn bất kỳ cột nào bạn muốn từ bảng đó trong đó id = danh tính bạn nhận được từ scope_identity

Xem tại đây để biết thông tin MSDN http://msdn.microsoft.com/en-us/l Library / ms190315.aspx

|
3

giải pháp tốt nhất và chắc chắn nhất là sử dụng SCOPE_IDENTITY. chỉ cần bạn có được danh tính phạm vi sau mỗi lần chèn và lưu nó vào một biến vì bạn có thể gọi hai lần chèn trong cùng một phạm vi. @identity và @@ danh tính có thể chúng hoạt động nhưng chúng không phải là phạm vi an toàn. bạn có thể có vấn đề trong một ứng dụng lớn

  declare @duplicataId int
  select @duplicataId =   (SELECT SCOPE_IDENTITY())

Chi tiết hơn là ở đây tài liệu Microsoft

|
2

* Thứ tự tham số trong chuỗi kết nối đôi khi rất quan trọng. * Vị trí của tham số Nhà cung cấp có thể phá vỡ con trỏ recordset sau khi thêm một hàng. Chúng tôi đã thấy hành vi này với nhà cung cấp SQLOLEDB.

Sau khi một hàng được thêm vào, các trường hàng không có sẵn, KHÔNG GIỚI HẠN Nhà cung cấp được chỉ định làm tham số đầu tiên trong chuỗi kết nối. Khi nhà cung cấp ở bất kỳ đâu trong chuỗi kết nối ngoại trừ tham số đầu tiên, các trường hàng mới được chèn sẽ không khả dụng. Khi chúng tôi di chuyển Nhà cung cấp đến tham số đầu tiên, các trường hàng xuất hiện một cách kỳ diệu.

|
  • 1

    Bạn có thể cho chúng tôi biết câu trả lời nhận xét này / có liên quan đến câu hỏi đã được hỏi không? Tôi không cảm thấy nó xứng đáng mũ / đậm. Nếu câu trả lời của bạn được coi là hữu ích, người dùng sẽ bỏ phiếu.

    – Lin ShiNu 22:01:26 05/08/2015
  • 1

    Rất nhiều người dùng có thể đã truy cập trang này vì họ không có các trường hợp lệ để xác định hàng vừa thêm. Hành vi này chúng tôi đã tìm thấy (chỉ đơn giản là thay đổi thứ tự các tham số trong chuỗi kết nối cho phép truy cập vào hàng mới được thêm ngay lập tức) rất kỳ lạ đến nỗi tôi nghĩ rằng nó đáng được đề cập trong mũ, đặc biệt là vì nó rất có thể sẽ khắc phục lý do mọi người muốn cái mới ID hàng và các trường khác của hàng đó. Chỉ cần đặt nhà cung cấp làm tham số đầu tiên, vấn đề sẽ biến mất.

    – Dương Gia Hiệp 23:55:18 06/08/2015
  • 1

    Bạn cần chỉnh sửa và cải thiện câu trả lời của bạn. Nó hiện đang ồn ào và không đi qua như một câu trả lời đàng hoàng hay thậm chí là một nỗ lực

    – Trịnh Kim Thanh 18:46:25 31/08/2015
  • 1

    Chính xác thì bạn có ý gì khi "ồn ào"? Bạn cần giải thích khiếu nại của bạn. Nó đơn giản như nó có thể được. Nếu bạn thay đổi thứ tự của các tham số trong chuỗi kết nối của mình, điều đó có thể ảnh hưởng đến việc liệu dữ liệu hàng có khả dụng sau khi chèn hay không.

    – Hồ Thái Thanh 21:32:26 01/09/2015
1

Đây có thể là một trường học cũ, nhưng có rất nhiều người sử dụng PHP cũ hơn, Pre 5.5 để chính xác hơn. Thông tin chi tiết có thể được tìm thấy tại http://php.net/manual/en/feft.mysql-insert-id.php

$last = mysql_insert_id();
|
0

Bạn có thể nối một câu lệnh chọn vào câu lệnh chèn của bạn. Số nguyên myInt = Chèn vào giá trị bảng1 (FName) ('Fred'); Chọn Phạm vi_Identity (); Điều này sẽ trả về một giá trị của danh tính khi thực hiện scaler.

|
0

Đây là cách tôi sử dụng OUTPUT INSERTED, khi chèn vào bảng sử dụng ID làm cột nhận dạng trong SQL Server:

'myConn is the ADO connection, RS a recordset and ID an integer
Set RS=myConn.Execute("INSERT INTO M2_VOTELIST(PRODUCER_ID,TITLE,TIMEU) OUTPUT INSERTED.ID VALUES ('Gator','Test',GETDATE())")
ID=RS(0)
|

Câu trả lời của bạn (> 20 ký tự)

Bằng cách click "Đăng trả lời", bạn đồng ý với Điều khoản dịch vụ, Chính sách bảo mật and Chính sách cookie của chúng tôi.

Không tìm thấy câu trả lời bạn tìm kiếm? Duyệt qua các câu hỏi được gắn thẻ hoặc hỏi câu hỏi của bạn.