如果我需要成员(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
答案 0 :(得分:3)
表值函数只能在单个SELECT
语句的范围内使用。它无法执行DML
,捕获异常等。
另一方面,它可以返回一个可以立即与同一查询中的另一个记录集连接的集合。
如果使用DML
或者不需要在基于集合的语句中使用输出参数,请使用存储过程;否则创建一个TVF
。
答案 1 :(得分:1)
一个调用函数的存储过程:-)我认为要么适合你...如果你的应用程序使用存储过程来查询数据库,那么最好保持一致...如果你使用ORM,它可能无法识别这个功能......我认为你也不会出错。
在我的一个应用程序中,我们更倾向于使用函数方法,从另一个角度来看。
HTH。
答案 2 :(得分:1)
使用输出参数存储过程,您只能返回两个值:@outID
和@amount
。
使用表值函数,您将能够返回一整套(outID, amount)
tuples。此外,只要在查询中允许表或视图表达式,就可以使用表值函数,例如:
SELECT dbo.Test(1) AS TestValues
答案 3 :(得分:1)
我认为输出参数方法是最理想的。这使得它更自我记录,预计不会超过一个元组,我认为可能更有效。
答案 4 :(得分:1)
如果我需要获取表格值,我只会使用表格评估的函数。
如果输出中只有一个“行”,那么最好在存储过程中使用输出参数。
一个例外是,如果您的SP / UDF可以写成单个SELECT
语句 - 即Inline Function - 因为如果您需要执行类似连接的操作,SQL Server可以进行更好的优化它到另一个查询的输出。您现在可能不会这样做,但是编写内联UDF意味着如果有人在将来以这种方式开始使用它,那么您将不会因为慢速的糖蜜查询和超时报告而措手不及。
如果这些都不适用于您,那么我会使用存储过程,原因如下;当你没有真正支持它们时,你不想创建基于集合的语义的错觉。
答案 5 :(得分:1)
输出参数。
多语句表值函数难以跟踪和调整。坚持使用更容易排除故障的存储过程。
此外,您仅限于在udf中可以执行的操作。假设您需要添加日志记录,或稍后调用扩展存储过程...您不能使用udf。
答案 6 :(得分:0)
我认为你最好的选择是SP,因为使用TBF(表值函数)你必须遍历表格以获得你的价值。
请记住,如果你在SQL中遍历表,那么你需要使用一个CURSOR(这不是太糟糕,但使用起来可能有点棘手)。