代码之家  ›  专栏  ›  技术社区  ›  bonCodigo

返回日期数组的SQL UDF

  •  3
  • bonCodigo  · 技术社区  · 10 年前

    我目前已经编写了一个小UDF(表值类型)来返回一个 table 开始日期和结束日期之间的日期。已从另一个表中检索开始和结束日期。

    Start_End_Table
    WeekNumber | Start Date | End Date
    

    功能:

    CREATE FUNCTION [dbo].[DatesBetween](@startDate datetime, @endDate datetime)
    RETURNS @dates TABLE (
       DateValue datetime NOT NULL
    ) 
    AS
    BEGIN
       WHILE (@startDate <= @endDate) BEGIN
          INSERT INTO @dates VALUES (@startDate);
          SET @startDate = DATEADD(day, 1, @startDate);
       END;
    
       RETURN;
    END;
    

    到目前为止,我一直以以下方式使用此功能:,

    SELECT * FROM [dbo].[DatesBetween](@startDate datetime, @endDate datetime);
    

    接下来,我需要从start_end_Date表中获取开始日期和结束日期,并调用该函数。因此,我不认为返回 桌子 不再是一种选择。我如何使此函数返回日期数组而不是表?或者我还有什么其他的方法可以结束这件事吗?

    1 回复  |  直到 10 年前
        1
  •  2
  •   Solomon Rutzky    10 年前

    尝试CROSS APPLY,因为它将为JOINed表中的每一行运行函数:

    SELECT [Date Value]
    FROM dbo.Start_End_Table dates
    CROSS APPLY [dbo].[DatesBetween](dates.StartDate, dates.EndDate)
    WHERE [Week Number]=@WeekNumber;
    

    示例输出类似于开始日期=1/1/2014,结束日期=1/3/2014,@weeknumber=1:

     | DateValue
      1/1/2014
      1/2/2014
      1/3/2014
    

    SQL Fiddle

    编辑:
    尝试以下内联表值函数,因为它将比多行TVF快得多,因为:

    1. 内联TVF固有地比多线TVF更快
    2. 它是基于设置的,而不是依赖于WHILE循环

    --

    CREATE FUNCTION dbo.GetDates(@StartDate DATETIME, @EndDate DATETIME)
    RETURNS TABLE
    AS RETURN
    WITH cte AS
    (
        SELECT ROW_NUMBER() OVER (ORDER BY (SELECT NULL)) AS [RowNum]
        FROM sys.objects WITH (NOLOCK)
    )
    SELECT DATEADD(DAY, (cte.[RowNum] - 1), @StartDate) AS [DateValue]
    FROM cte
    WHERE cte.[RowNum] < (DATEDIFF(DAY, @StartDate, @EndDate) + 2);
    GO
    
    SELECT * FROM dbo.GetDates('1/1/2014', '1/3/2014');