2010-06-29 84 views
37

將記錄插入到具有標識列的表中時,可以使用SCOPE_IDENTITY()獲取該值。在存儲過程中的情況下,這將是返回的標識值的推薦的方法:存儲過程 - 返回標識作爲輸出參數或標量

  1. 作爲輸出參數SET @RETURN_VALUE = SCOPE_IDENTITY()
  2. 作爲一個標SELECT SCOPE_IDENTITY()
  3. 另一種方式?

對每個人有利/弊嗎?

回答

33

它的全部取決於您的客戶端數據訪問層。許多ORM框架依賴於在插入操作期間顯式查詢SCOPE_IDENTITY。

如果您完全控制數據訪問層,那麼返回SCOPE_IDENTITY()作爲輸出參數可能會更好。在結果集中包裝返回會增加不必要的元數據開銷以描述結果集,並使代碼複雜化以處理請求結果。

如果你喜歡一個結果集返回,然後再是值得商榷更好地使用OUTPUT子句:

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

這樣你就可以得到整個插排後面,包括默認和計算列,並你會得到一個結果集,每行插入一行,這對於面向集合的批量插入來說是正確的。

總體而言,返回SCOPE_IDENTITY()時我看不到一個案例,因爲結果集是一個很好的做法。

+0

如果存在多個插入,則返回多行的好處。也許gbn擊敗你,但你的更徹底。在我的特殊情況下,我沒有使用ORM,並且(現在)不會一次插入多個記錄。 – 2010-06-29 21:15:15

+1

@Remus:你說過,「總體而言,在返回SCOPE_IDENTITY()作爲結果集時,我看不到一個單獨的案例,這將是一個很好的做法。」那麼該怎麼辦呢?您是否暗示SCOPE_IDENTITY()的整體使用是不好的做法?請問在什麼意義上? – Fandango68 2016-05-23 02:01:13

+3

@ Fernando68:我說你應該把它作爲輸出參數,而不是結果集 – 2016-05-23 07:42:09

3

我更喜歡將標識值作爲輸出參數返回。 SP的結果應表明它是否成功。值爲0表示SP成功完成,非零值表示錯誤。此外,如果您需要進行更改並從SP返回附加值,則除了添加其他輸出參數外,您無需進行任何更改。

+0

對於它的價值,同樣的道理也適用於選項1或2,如果你需要添加另一個輸出值,你既可以添加新的參數下,選擇1或者其他的字段添加到您的在選項2下選擇(或者另一個選擇,如果你的用戶支持它的話)。我更喜歡選項1,它基於一個未經證實的假設,即數據庫和/或客戶端需要較少的「開銷」。 – 2010-06-29 17:24:00

+0

我與jmgant就此合作。選擇一個額外的列並不難。我知道你可以使輸入參數爲可選的(使用默認值);輸出參數怎麼樣?如果你不能,那麼更改'SELECT'會更容易,因爲除非需要,否則可能會忽略額外的列。儘管如此,我認爲輸出參數是「適當」的方式,沒有結果集的開銷。 – 2010-06-29 21:10:18

38

另一個選擇將作爲存儲過程的返回值(我不建議這樣做,因爲這通常是最好的錯誤值)。

我已經將它包括在當它插入單行時存儲過程被其他SQL過程使用以及無法與OUTPUT參數一起工作的前端(.NET中的IBATIS I相信):

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 

輸出參數很容易從其他存儲過程調用IMO時在T-SQL的工作,但一些編程語言有差或輸出參數不支持與結果集更好地工作。

+0

這兩種方法都是很好的例子,儘管我不認爲我會同時做這兩件事,除非我有充分的理由相信兩者都需要,例如,如果我不知道什麼語言會消耗我的過程並知道它需要支持這兩種方法。 – 2010-06-29 17:16:23

+0

是的。我不應該說「通常」。我在需要訪問這兩種輸出形式的環境中使用了這兩種方法。我會重新回答我的答案。 – 2010-06-29 17:31:34

1

作爲記錄集或輸出參數。後者的開銷較小,我傾向於使用它而不是單列/行記錄集。

如果我預計> 1點的行我會使用OUTPUT子句和一個記錄

返回值通常會被用於錯誤處理。

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

請編輯更多信息。只有代碼和「試試這個」的答案是[灰心](http://meta.stackexchange.com/questions/196187/is-try-this-bad-practice),因爲它們不包含可搜索的內容,也不解釋爲什麼有人應該「嘗試這個」。 – 2015-09-15 15:35:34

相關問題