3

哪種方法更好,如果我需要一個成員(SP或FUNC)返回2個參數的使用方法:輸出參數與表值函數的存儲過程?

CREATE PROCEDURE Test 
    @in INT, 
    @outID INT OUT, 
    @amount DECIMAL OUT 
AS 
BEGIN 
    ... 
END 

CREATE FUNCTION Test 
(
    @in INT 
) 
RETURNS @ret TABLE (outID INT, amount DECIMAL) 
AS 
BEGIN 
    ... 
END 

什麼是每種方法的利弊考慮到結果將傳遞到另一個存儲過程:

EXEC Foobar @outID, @outAmount 

回答

3

表值函數只能在單個SELECT語句的範圍內使用。它不能執行DML,捕獲異常等。

另一方面,它可以返回一個可以立即在同一個查詢中與另一個記錄集聯接的集合。

如果您使用DML或不需要在基於集合的語句中使用輸出參數,請使用存儲過程;否則創建一個TVF

+0

+1兩者的好處和侷限性的最佳解釋,但由於'only'這個問題想要在存儲過程中使用返回的值,而不是Select語句(他們可能會後悔),所以存儲過程會獲勝。 – JeffO 2010-03-28 18:40:07

+0

這裏'DML'是什麼意思? – Niklas 2014-03-20 09:46:32

+1

@Niklas:http://en.wikipedia.org/wiki/Data_manipulation_language – Quassnoi 2014-03-20 09:53:17

1

調用函數的存儲過程:-)我認爲要麼適合你......如果你的應用程序使用存儲過程來查詢數據庫,那麼最好是保持一致......如果你使用ORM,它可能無法識別函數...... I不要以爲自己會犯錯。

在我的一個應用程序中,我們更喜歡使用函數方法來拋出另一個視角。

HTH。

0

我認爲你最好的選擇是SP,因爲使用TBF(表值函數)時,你必須遍歷表來獲得你的價值。請記住,如果您在SQL中遍歷表,那麼您將需要使用CURSOR(這不是太糟糕,但可能有點棘手)。

+1

從test(@in)中選擇@outid = outid;有什麼迭代?如果一個proc基於業務邏輯返回一組值,那麼表函數也可以。 – JeffO 2010-03-28 18:45:14

1

使用輸出參數的存儲過程,您只能返回兩個值:@outID@amount

使用表值函數,您將能夠返回整套(outID, amount)tuples。此外,可以使用一個表值函數無論表或視圖表達式中的查詢是允許的,如:

SELECT dbo.Test(1) AS TestValues 
+0

所以如果我需要返回2個值,我不需要使用func? – abatishchev 2010-03-28 14:22:16

+0

是的,它可能看起來像SP是你的情況下更好的選擇。請注意,與存儲過程不同,表值函數也可用於查詢。 – 2010-03-28 14:24:22

1

我認爲輸出參數的方法是最可取的。這使得它更自我記錄,預計不會超過一個元組,並且我認爲可能會更有效率。

1

我只會使用 -valued函數,如果我需要獲得值。

如果在輸出中只有一個「行」,那麼最好在存儲過程中使用輸出參數。

一個例外是如果你的SP/UDF可以寫成一個單一的SELECT聲明 - 即一個Inline Function - 因爲如果您需要執行某些操作(如將它連接到另一個查詢的輸出),SQL Server可以做出更好的優化。您現在可能沒有這樣做,但是編寫內聯UDF意味着如果有人開始以這種方式使用它,就不會因慢糖漿查詢和超時報告而發出警報。

如果這些都不適用於您,那麼我將使用存儲過程,原因概述如下:當你不真正支持它們時,你不想創建基於集合的語義的錯覺。

1

輸出參數。

多語句表值函數很難追蹤和調整。堅持更容易排除故障的存儲過程。

此外,你僅限於你可以在udf中做什麼。假設你需要添加日誌記錄,或者稍後調用一個擴展的存儲過程...你不能使用udf。