将标量UDF重写为表UDF或在存储过程中插入UDF

时间:2018-12-10 12:22:40

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

在存储过程中,我创建了一个临时表来提高性能。

在存储过程中使用实际的select语句时,使用了多个标量UDF,临时表替换了它们:

INSERT INTO #BEDRAGEN
    SELECT 
        DD.ColumnA, DD.ColumnB, DD.ColumnC, 
        ISNULL(DBO.SIF_get_SalesAmount(DD.ColumnA, DD.ColumnB, DD.ColumnC), 0) AS Totaalbedrag,
    FROM 
        T_InvoiceDetailDosDet as IDD

我的问题是:如果要提高性能,我想用代码替换dbo.SIF_get_SalesAmount或将标量UDF制成表表。

此UDF中的内容是什么

退还金额。

它读取文件并计算出几件事,然后才得出总数。

该函数有3个参数输入和Amount输出。

UDF片段:

ALTER FUNCTION [dbo].[SIF_get_SalesAmountDosDetail] 
    (@A VARCHAR(20),
     @B VARCHAR(20),
     @C VARCHAR(20) 
    )
RETURNS NUMERIC(12,2)
AS
    DECLARE @SalesAmount NUMERIC(12,2)
    ,       @SalesUnitOfAccount TINYINT
    ,       @Unit NCHAR(5)
    ,       @SalesUnit NCHAR(5)
    ,       @TotalUnits  NUMERIC(15, 3)

    SELECT        
        @unit = p.Unit,
        @SalesUnit = p.SalesUnit,
        @SalesUnitOfAccount = dd.SalesUnitOfAccount
    FROM 
        dbo.T_table p
    WHERE
        p.ColumnA = @A AND p.ColumnB = @B AND p.ColumnC = @C

    SELECT @rc = @@ROWCOUNT

    IF @rc <> 1
    BEGIN
        SELECT @SalesAmount = 0
        RETURN @SalesAmount
    END

    IF @SalesUnit = 0
    BEGIN
        SELECT @SalesUnit = 1
    END

    -- several calculations follow based on values of @Unit etc.
    --  at the end of the UDF:
    --  last if then else calculation and then returning the Amount.
    IF @SalesUnitOfAccount = 4
    BEGIN
        SELECT @PricePerDesc = @SalesUnit
        SELECT @SalesAmount = CONVERT(numeric(12, 2), round((@CurrPrice * (@TotalSalesUnits / @SalesComputQty)) - @DiscAmount, 2))
    END

    SELECT @TotalSalesAmount = @TotalSalesAmount + ISNULL(@SalesAmount, 0)

    -- Return the result of the function
    RETURN @TotalSalesAmount

我可以通过什么方式在存储过程选择中插入此UDF代码?还是我可以用什么方法将其设为UDF_table函数?

感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

您所要的恰恰是SQL Server 2019(从CTP2.1起)最近宣布的称为“ Scalar UDF Inlining”的功能的重点。此功能通过自动将UDF的逻辑嵌入(或内联)到调用查询中而起作用。您可以通过免费下载来尝试一下。

如果您想知道它在幕后的工作方式,可以在最近的研究论文“ Froid: Optimization of Imperative programs in a Relational Database”中找到详细信息。该论文描述了一种系统方法,可以将整个UDF表示为SQL,您可以使用它。标量UDF内联功能基于Froid,在许多情况下可以带来巨大的性能提升。

[披露:我是Froid论文的共同作者]