【问题标题】:SQL - Pass Table to a UDF in a SelectSQL - 将表传递给选择中的 UDF
【发布时间】:2012-05-12 03:04:23
【问题描述】:

我有一个 UDF,它接受一个表作为参数(一个 2 列的表)并输出一个字符串,很像 article。我有一个表,我想将 UDF 应用于多个列,如下所示:

Date   Unit   Line   Revenue   Orders
4/1/12 D      R      20.00     3
4/2/12 D      R      25.00     4
4/1/12 H      W      33.00     1
4/2/12 H      W      35.00     3

我想在此表中具有最新日期的每一行上调用我的 UDF,并向 UDF 传递一个表,其中包含每个不同单位和行的日期和收入列。而且我还想调用 UDF 并为每个不同的单元和行传递日期和订单。这是一份报告,UDF 将始终通过 Date 列和我想对其应用一些计算并存储和报告的另一列。所以我看了很多东西,包括 CROSS APPLY,我想做这样的事情:

SELECT        T.unit
              , T.line
              , dbo.fn_myUDF((SELECT T2.Date, T2.Revenue FROM #Table T2)) as UDFRevenueResult
              , dbo.fn_myUDF((SELECT T2.Date, T2.Orders FROM #Table T2)) as UDFOrderResult
FROM          #Table T
WHERE         T.Date = @ReportDate

这给了我错误“当 EXISTS 未引入子查询时,选择列表中只能指定一个表达式。”我查看了 CROSS APPLY 但这似乎只适用于您返回表变量时。因此,我可能可以通过使用游标和循环来回答我自己的问题,并在每次循环迭代中构建我想传递给 UDF 的每个表,但这似乎并不正确。谁能告诉我如何在 SQL Server 2008 中做我想做的事?

【问题讨论】:

    标签: sql sql-server sql-server-2008 parameters user-defined-functions


    【解决方案1】:

    不能像这样使用子查询在查询的 SELECT 部分返回表变量。它们只能返回一个值。如:

    set @myParam = (select myvalue from table where primarykey = 1)
    

    set @myParam = (select top 1 myvalue from table)
    

    但是,考虑到您的子查询与被选择的行没有任何关系,您可以这样做。

    declare @t1 table (DateTime c1, float c2)
    insert @t1
    SELECT Date, Revenue 
    FROM #Table 
    
    declare @t2 table (DateTime c1, int c2) -- not sure on data type of 'Orders'
    insert @t2
    SELECT Date, Orders FROM #Table
    
    
    SELECT T.unit               
         , T.line               
         , dbo.fn_myUDF(@t1) as UDFRevenueResult               
         , dbo.fn_myUDF(@t2) as UDFOrderResult 
    FROM #Table T 
    WHERE T.Date = @ReportDate 
    

    【讨论】:

    • 我害怕那个。有没有办法可以轻松地将表格按不同的单元和线拆分为子表?还是只需要为要传递 UDF 的每个单元/行和列创建一个表?
    • @deusxmach1na - 您是否试图将每一行视为一个表格?
    • 不是每一行,而是所有具有相同 Unit 和 Line 的行都应该是一个表。我的 UDF 将采用 Date 列和 Revenue 列并对其进行计算,我希望它对每个不同的 Unit 和 Line 值执行该计算。所以在我的示例表中,我希望前两行作为一个表,因为它们是 Unit D 和 Line R,而接下来的两行作为另一个表,因为它们是 Unit H 和 line W。
    • 我现在有一个可行的解决方案,谢谢!我使用 ROW_NUMBER() OVER (PARTITION BY Unit, Line ORDER BY Date DESC) 在我想开始一个新表的每一行中放置一个 1,并遍历该列来构建我的表。无论如何,你回答了我原来的问题,所以谢谢!
    • 一个简短的说明。 DECLARE @t1 TABLE 应该是 DECLARE @t1 as dbo.MyTableType,因为我的 UDF 期望将我的特定 TableType 作为参数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-11
    • 2017-12-11
    • 1970-01-01
    • 2019-04-02
    • 2021-06-19
    • 1970-01-01
    相关资源
    最近更新 更多