2009-06-10 48 views
11

Tôi đang chèn vào một bảng SQLServer với một trường khóa tự động. (Tôi tin rằng điều này được gọi là một cột IDENTITY trong SQLServer.)Làm cách nào để trả lại giá trị cột IDENTITY mới từ câu lệnh SQLServer SELECT?

Trong Oracle, tôi có thể sử dụng từ khóa LẠI để cung cấp cho câu lệnh INSERT tôi một kết quả thiết lập như một truy vấn SELECT sẽ trả về giá trị được tạo ra:

INSERT INTO table 
(foreign_key1, value) 
VALUES 
(9, 'text') 
RETURNING key_field INTO :var; 

Làm cách nào để thực hiện điều này trong SQLServer?

Thưởng: Ok, các câu trả lời hay cho đến giờ, nhưng làm cách nào để đưa câu trả lời vào một câu lệnh duy nhất, nếu có thể? :)

+0

Đã thêm ví dụ "một cuộc gọi". – gbn

Trả lời

17

Nói chung, nó không thể được thực hiện trong một câu lệnh duy nhất.

Nhưng SELECT SCOPE_IDENTITY() có thể (và nên) được đặt trực tiếp sau câu lệnh INSERT, vì vậy tất cả được thực hiện trong cùng một cuộc gọi cơ sở dữ liệu.

Ví dụ:

mydb.ExecuteSql("INSERT INTO table(foreign_key1, value) VALUES(9, 'text'); SELECT SCOPE_IDENTITY();"); 

Bạn có thể sử dụng OUTPUT, nhưng nó có một số hạn chế bạn nên biết:

http://msdn.microsoft.com/en-us/library/ms177564.aspx

+4

Không thể tin được. Tôi không biết mình có thể kết hợp những câu như thế. Thông minh, phi tiêu chuẩn, ghê tởm, hữu ích ... tất cả những tính từ này đến với tâm trí. :) – skiphoppy

+1

Nó có thể được thực hiện trong một câu lệnh trong SQL Server 2005 với OUTPUT – gbn

9
SELECT SCOPE_IDENTITY() 

Edit: Có một vở kịch ...

Nếu chỉ mệnh đề OUTPUT hỗ trợ các biến địa phương.

Dù sao, để có được một loạt các ID chứ không phải là một singleton

DECLARE @Mytable TABLE (keycol int IDENTITY (1, 1), valuecol varchar(50)) 

INSERT @Mytable (valuecol) 
OUTPUT Inserted.keycol 
SELECT 'harry' 
UNION ALL 
SELECT 'dick' 
UNION ALL 
SELECT 'tom' 

Chỉnh sửa 2: Trong một cuộc gọi. Tôi chưa bao giờ có dịp sử dụng cấu trúc này.

DECLARE @Mytable TABLE (keycol int IDENTITY (1, 1), valuecol varchar(50)) 

INSERT @Mytable (valuecol) 
OUTPUT Inserted.keycol 
VALUES('foobar') 
+0

Tôi thứ hai này. SCOPE_IDENTITY() trả về danh tính gần đây nhất trong phạm vi truy vấn gần đây nhất của bạn. Các phương thức khác @@ IDENTITY và IDENT_CURRENT() arent giới hạn ở một phạm vi cụ thể –

+0

hhmm một downvote ẩn danh cho câu trả lời này ... – gbn

2

SCOPE_IDENTITY

4

Ngoài @@ IDENTITY, bạn cũng nên xem xét SCOPE_IDENTITY() và IDENT_CURRENT(). Bạn có thể muốn SCOPE_IDENTITY(). @@ IDENTITY có vấn đề ở chỗ nó có thể trả lại giá trị danh tính được tạo trong trình kích hoạt trên bảng thực tế mà bạn đang cố gắng theo dõi.

Ngoài ra, đây là các hàm giá trị đơn. Tôi không biết từ khóa Oracle RETURNING hoạt động như thế nào.

0

Bạn có thể sử dụng OUTPUT INTO, có các lợi ích bổ sung khi có thể nắm bắt nhiều danh tính được chèn.

0

INSERT INTO bảng (foreign_key1, giá trị) GIÁ TRỊ (9, 'văn bản'); SELECT @@ IDENTITY;

2

Tùy thuộc vào ngữ cảnh gọi điện của bạn.

Nếu bạn đang gọi điều này từ mã máy khách, bạn có thể sử dụng OUTPUT và sau đó đọc giá trị trả về.

DECLARE @t TABLE (ColID int IDENTITY, ColStr varchar(20)) 

INSERT INTO @t (ColStr) 
OUTPUT Inserted.ColID 
VALUES ('Hello World') 

Kết quả:

 ColID 
----------- 
      1 

Nếu bạn đang gói này trong một thủ tục lưu trữ, sử dụng OUTPUT là làm việc nhiều hơn. Ở đó, bạn sẽ muốn sử dụng SCOPE_IDENTITY(), nhưng bạn không thể làm điều đó trong một câu lệnh duy nhất. Chắc chắn, bạn có thể đặt nhiều câu lệnh trên một dòng với dấu ';' dấu phân cách, nhưng đó không phải là một câu lệnh duy nhất.

DECLARE @idValue int 
DECLARE @t TABLE (ColID int IDENTITY, ColStr varchar(20)) 

INSERT INTO @t (ColStr) VALUES ('Hello World') 

SELECT @idValue = SCOPE_IDENTITY() 

Kết quả: @idValue biến chứa giá trị nhận dạng. Sử dụng tham số OUTPUT để trả về giá trị.

Các vấn đề liên quan