【问题标题】:Stored procedure with output parameters vs. table-valued function?具有输出参数的存储过程与表值函数?
【发布时间】:2011-02-01 18:08:43
【问题描述】:

如果我需要返回 2 个参数的 member(sp 或 func),使用哪种方法更好:

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

【问题讨论】:

    标签: sql sql-server tsql stored-procedures user-defined-functions


    【解决方案1】:

    调用函数的存储过程 :-) 我认为两者都适合您...如果您的应用程序使用存储过程来查询数据库,那么最好保持一致...如果您使用 ORM,它可能无法识别该功能...我认为您也不会出错。

    在我的一个应用程序中,我们更喜欢使用函数方法,以换一种视角。

    HTH。

    【讨论】:

      【解决方案2】:

      我认为你最好选择 SP,因为使用 TBF(表值函数)你必须遍历表来获得你的值。

      请记住,如果您在 SQL 中遍历表,那么您将需要使用 CURSOR(还不错,但使用起来可能有点棘手)。

      【讨论】:

      • 选择@outid = outid from test(@in);有什么可以迭代的?如果 proc 根据业务逻辑返回一组值,那么 table 函数也可以。
      【解决方案3】:

      使用使用输出参数的存储过程,您将只能返回两个值:@outID@amount

      使用表值函数,您将能够返回一整套(outID, amount)tuples。此外,在查询中允许使用表或视图表达式的任何地方都可以使用表值函数,例如:

      SELECT dbo.Test(1) AS TestValues
      

      【讨论】:

      • 所以如果我需要准确返回 2 个值,我不需要使用 func 吗?
      • 是的,在您的情况下,SP 似乎是更好的选择。请注意,与存储过程不同,表值函数也可以在查询中使用。
      【解决方案4】:

      我认为输出参数方法是最可取的。这使得它更加自我记录,预计不超过一个元组,我认为可能会更有效。

      【讨论】:

        【解决方案5】:

        表值函数只能在单个SELECT 语句的范围内使用。它不能执行DML、捕获异常等。

        另一方面,它可以返回一个集合,该集合可以立即与同一查询中的另一个记录集连接。

        如果你使用DML或者不需要在set-based statements中使用输出参数,使用stored proc;否则创建一个TVF

        【讨论】:

        • +1 对两者的优点和局限性的最佳解释,但由于问题“仅”想在存储过程中使用返回值而不是 Select 语句(他们以后可能会后悔),存储过程获胜。
        • 这里的DML 是什么意思?
        【解决方案6】:

        如果我需要获取 table 值,我只会使用 table 值函数。

        如果您的输出中只有一个“行”,那么最好在存储过程中使用输出参数。

        如果您的 SP/UDF 可以编写为单个 SELECT 语句(即 Inline Function),则有一个例外,因为如果您需要执行诸如将其连接到输出的操作,SQL Server 可以进行更好的优化另一个查询。您现在可能不会这样做,但编写内联 UDF 意味着如果将来有人开始以这种方式使用它,您将不会因慢如蜜糖的查询和超时报告而措手不及。

        如果这些都不适用于您,那么出于概述的原因,我将使用存储过程;当您实际上不支持基于集合的语义时,您不希望产生这种错觉。

        【讨论】:

          【解决方案7】:

          输出参数。

          多语句表值函数难以跟踪和调整。坚持使用更容易排除故障的存储过程。

          此外,您只能在 udf 中进行操作。假设您需要添加日志记录,或者稍后调用扩展存储过程...您不能为此使用 udf。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2015-04-28
            • 1970-01-01
            • 1970-01-01
            • 2016-03-24
            • 1970-01-01
            • 1970-01-01
            • 2011-05-14
            • 2018-08-08
            相关资源
            最近更新 更多