2010-06-29 28 views
37

Khi bạn chèn bản ghi vào bảng có cột nhận dạng, bạn có thể sử dụng SCOPE_IDENTITY() để nhận giá trị đó. Trong bối cảnh của một thủ tục lưu trữ, đó sẽ là cách khuyến khích để trả về giá trị bản sắc:Thủ tục lưu sẵn - nhận dạng trả về làm tham số đầu ra hoặc vô hướng

  1. Là một tham số đầu ra SET @RETURN_VALUE = SCOPE_IDENTITY()
  2. Là một đại lượng vô hướng SELECT SCOPE_IDENTITY()
  3. Một cách khác?

Bất kỳ ưu điểm/khuyết điểm nào đối với mỗi?

Trả lời

33

Tất cả phụ thuộc vào lớp truy cập dữ liệu khách hàng của bạn. Nhiều khung công tác ORM dựa trên truy vấn một cách rõ ràng SCOPE_IDENTITY trong quá trình chèn.

Nếu bạn hoàn toàn kiểm soát lớp truy cập dữ liệu thì tốt hơn là trả về SCOPE_IDENTITY() làm tham số đầu ra. Việc đưa trả về trong một tập kết quả thêm các chi phí dữ liệu meta không cần thiết để mô tả tập kết quả và làm phức tạp mã để xử lý kết quả yêu cầu.

Nếu bạn muốn có một sự trở lại kết quả thiết lập, sau đó một lần nữa là đáng tốt hơn để sử dụng mệnh đề OUTPUT:

INSERT INTO MyTable (col1, col2, col3) 
OUTPUT INSERTED.id, col1, col2, col3 
VALUES (@col1, @col2, @col3); 

Bằng cách này bạn có thể nhận được toàn bộ chèn hàng trở lại, trong đó có các cột mặc định và tính toán, và bạn nhận được một tập kết quả có chứa một hàng cho mỗi hàng được chèn vào, điều này làm việc đúng với chèn hàng loạt được đặt theo định hướng.

Nhìn chung, tôi không thể nhìn thấy một trường hợp đơn lẻ khi trả lại SCOPE_IDENTITY() do tập hợp kết quả sẽ là một phương pháp hay.

+0

Điểm tốt khi trả về nhiều hàng nếu có nhiều lần chèn. Có lẽ gbn đánh bại bạn với điều đó, nhưng bạn đã triệt để hơn. Trong trường hợp cụ thể của tôi, tôi không sử dụng ORM và (hiện tại) sẽ không chèn nhiều bản ghi cùng một lúc. –

+1

@Remus: bạn nói, "Nói chung, tôi không thể nhìn thấy một trường hợp duy nhất khi trở về SCOPE_IDENTITY() như là một tập hợp kết quả sẽ là một thực hành tốt." Sau đó, làm thế nào khác nó có thể được thực hiện? Bạn có ngụ ý việc sử dụng tổng thể SCOPE_IDENTITY() là thực hành không tốt? Trong ý nghĩa gì xin vui lòng? – Fandango68

+3

@ Fernando68: Tôi nói bạn nên lấy nó làm thông số đầu ra, không phải là kết quả được đặt –

3

Tôi muốn trả lại giá trị danh tính dưới dạng thông số đầu ra. Kết quả của SP phải cho biết liệu nó có thành công hay không. Giá trị bằng 0 cho biết SP đã hoàn tất thành công, giá trị khác 0 cho biết lỗi. Ngoài ra, nếu bạn cần thay đổi và trả về một giá trị bổ sung từ SP, bạn không cần thực hiện bất kỳ thay đổi nào ngoài việc thêm tham số đầu ra bổ sung.

+0

Đối với những gì đáng giá, cùng một lý do có thể được áp dụng cho tùy chọn 1 hoặc 2, nếu bạn cần thêm giá trị đầu ra khác, bạn có thể thêm thông số mới trong tùy chọn 1 hoặc thêm trường khác vào chọn (hoặc lựa chọn khác nếu người tiêu dùng của bạn hỗ trợ nó) theo tùy chọn 2. Tôi thích tùy chọn 1 bản thân mình, dựa trên một giả định không được chứng minh rằng nó đòi hỏi ít "overhead" trên một phần của cơ sở dữ liệu và/hoặc khách hàng. –

+0

Tôi đang sử dụng jmgant. Nó không phải là khó để 'SELECT' một cột bổ sung. Tôi biết bạn có thể tạo các tham số đầu vào tùy chọn (với giá trị mặc định); những gì về các thông số đầu ra? Nếu bạn không thể, việc thay đổi 'SELECT' dễ dàng hơn vì bạn có thể bỏ qua cột phụ trừ khi bạn cần nó. Mặc dù vậy, tôi nghĩ rằng các tham số đầu ra là "đúng" cách mà không có chi phí của một tập kết quả. –

38

Tùy chọn khác sẽ là giá trị trả lại cho quy trình được lưu trữ (Tôi không đề xuất điều này mặc dù, vì đó thường là tốt nhất cho các giá trị lỗi).

Tôi đã bao gồm cả hai khi nó chèn một hàng trong trường hợp thủ tục được lưu trữ đã được tiêu thụ bởi cả hai thủ tục SQL khác và giao diện người dùng không thể làm việc với tham số OUTPUT (IBATIS in .NET I tin):

CREATE PROCEDURE My_Insert 
    @col1   VARCHAR(20), 
    @new_identity INT OUTPUT 
AS 
BEGIN 
    SET NOCOUNT ON 

    INSERT INTO My_Table (col1) 
    VALUES (@col1) 

    SELECT @new_identity = SCOPE_IDENTITY() 

    SELECT @new_identity AS id 

    RETURN 
END 

Các tham số đầu ra là dễ dàng hơn để làm việc với trong T-SQL khi gọi từ thủ tục lưu trữ khác IMO, nhưng một số ngôn ngữ lập trình có nghèo hoặc không có hỗ trợ cho các thông số đầu ra và làm việc tốt hơn với bộ kết quả.

+0

Ví dụ tốt về cả hai cách để làm điều đó, mặc dù tôi không nghĩ rằng tôi sẽ làm cả hai cùng một lúc trừ khi tôi có lý do mạnh mẽ để tin cả hai là cần thiết, ví dụ, nếu tôi không biết ngôn ngữ nào sẽ tiêu thụ proc của tôi và biết nó cần thiết để hỗ trợ cả hai phương pháp. –

+0

Đúng. Tôi không nên nói, "thường". Tôi đã sử dụng cả hai phương pháp trong một môi trường mà chúng ta cần truy cập vào cả hai dạng đầu ra. Tôi sẽ viết lại câu trả lời của tôi. –

1

Hoặc là tham số bản ghi hoặc đầu ra. Cái sau có ít chi phí hơn và tôi có xu hướng sử dụng nó hơn là một bản ghi cột/hàng đơn.

Nếu tôi dự kiến> 1 hàng tôi muốn sử dụng mệnh đề OUTPUT và bản ghi

Giá trị trả về thường được sử dụng để xử lý lỗi.

1
SELECT IDENT_CURRENT('databasename.dbo.tablename') AS your identity column; 
+3

Vui lòng chỉnh sửa với nhiều thông tin hơn. Chỉ các câu lệnh mã và câu trả lời "dùng thử" này mới được [nản lòng] (http://meta.stackexchange.com/questions/196187/is-try-this-bad-practice), vì chúng không chứa nội dung có thể tìm kiếm và không giải thích tại sao ai đó nên "thử cái này". –

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