【问题标题】:How do you define a scalar-valued UDF?如何定义标量值 UDF?
【发布时间】:2011-12-31 15:47:25
【问题描述】:

我正在阅读 Microsoft 的 70-433 SQL Training Kit,我遇到了一个示例,他们将以下内容定义为“标量 UDF”:

CREATE FUNCTION dbo.fnGetCustomerAccountNumber(@CustomerID INT)
RETURNS VARCHAR(10)
AS
BEGIN
    RETURN ISNULL(
        (
        SELECT
            AccountNumber
        FROM Sales.Customer
        WHERE CustomerID = @CustomerID
    ), 'NOT FOUND');
END
GO

我知道标量 UDF(与表值 UDF 相对)是返回单个值的 UDF,但在我看来,如果仅返回一行,则上述函数只会返回单个值SELECT 语句 - 这将取决于表的内容。但我很高兴假设只会返回一行(如果没有会发生什么?)。但是……

然后他们给出了一个替代版本,而不是调用上面的 UDF,而是执行以下操作:

SELECT 
    soh.SalesOrderID
    , soh.OrderDate
    , ISNULL(
        (
        SELECT
            AccountNumber
        FROM Sales.Customer
        WHERE CustomerID = soh.CustomerID
    ), 'NOT FOUND')
FROM Sales.SalesOrderHeader AS soh;

他们对比第二个示例说“使用内联表值 UDF 不会导致与使用标量 UDF 相同的性能损失,因为......”

那么,即使代码与第一个相同,第二个示例也是表值 UDF 而不是标量 UDF?这是文本中的错误,还是我误解了标量 UDF 和表值 UDF 之间的区别?

【问题讨论】:

    标签: sql sql-server sql-server-2008


    【解决方案1】:

    有区别。看第一个中的where子句

       WHERE CustomerID = @CustomerID
    

    CustomerID 与单个整数值(这是一个参数)匹配。

    在第二个where子句中

       WHERE CustomerID = soh.CustomerID
    

    Sales.SalesOrderHeader 表中CustomerID 的每个值匹配。

    【讨论】:

    • 啊,我明白了。这非常微妙,因为我错过了对标量 UDF 的调用,如下所示: SELECT soh.SalesOrderID , soh.OrderDate , dbo.fnGetCustomerAccountNumber(soh.CustomerID) FROM Sales.SalesOrderHeader AS soh; ...它为 soh.CustomerID 的每个值调用 UDF ...但当然就 UDF 而言,它只被调用一次,而在第二个示例中,它为 soh.CustomerID 的每个值重复自身...因此是表值的。谢谢。
    • (很抱歉未能以可读的方式格式化第二个代码块。在我按 Enter 之前它看起来很好,此时它在手推车中陷入困境。任何关于如何更好的建议 -感谢收到格式化代码块)
    • 遗憾的是,您无法在 cmets 中格式化代码。您可以将它们放在反引号中,以使它们成为 unformated 作为代码。
    猜你喜欢
    • 2016-05-03
    • 1970-01-01
    • 2011-12-12
    • 2016-05-12
    • 2017-11-01
    • 2017-08-28
    • 2016-05-24
    • 2014-08-28
    相关资源
    最近更新 更多