如何将此代码更改为SQL 2012函数?

时间:2017-04-05 17:16:22

标签: sql sql-server function tsql sql-server-2012

 declare @startTime datetime
,@endTime datetime
, @IntervalIncWeekends int ;
set @startTime = '03/13/2017 11:00:02'
set @endTime = '03/30/2017 19:53:59'
IF DATENAME(dw, @startTime) = 'Saturday'
SET @startTime = CAST(CAST(DATEADD(dd,2,@startTime) AS DATE) AS 
DATETIME); 
IF            DATENAME(dw, @startTime) = 'Sunday'
SET  @startTime = CAST(CAST(DATEADD(dd,1,@startTime) AS DATE) AS 
DATETIME); 
IF DATENAME(DW, @endTime) = 'Saturday'
SET    @endTime = DATEADD(MI,-1, CAST(CAST(@endTime AS DATE) 
AS DATETIME));
IF DATENAME(DW, @endTime) = 'Sunday'
SET @endTime = DATEADD(MI,-1, CAST(CAST(DATEADD(dd,-1,@endTime) AS 
DATE) AS DATETIME));

IF @endTime <= @startTime
BEGIN
    SELECT 0;
END
ELSE
BEGIN
DECLARE       @NumberofWeekendDays decimal(5,2)  = 0;
 ;WITH cte as (
   SELECT CAST(DATEADD(DD,1,@startTime) AS DATE) AS dt
                           WHERE  DATEADD(DD,1,@startTime) < @endTime
                           UNION  ALL
                          SELECT DATEADD(DD,1,dt)
                           FROM   cte
                           WHERE  DATEADD(DD,1,dt) < @endTime
              )
              SELECT @NumberofWeekendDays = COUNT(*)
              FROM   cte
              WHERE  DATENAME(dw, dt) IN ('Saturday','Sunday');
                            SELECT ((DATEDIFF(MI,@startTime,@endTime) - 
(@NumberofWeekendDays * 60 * 24))/60)/24 m;
    END

如何将其更改为sql函数,以便我可以将2个日期作为参数传递给函数,并插入时间返回?

1 个答案:

答案 0 :(得分:1)

这是一个可以转换为表值函数甚至是标量值函数的选项。我强烈的推荐将是一个TVF。

您还可以选择排除假期。 (目前列为值,但也可以是表格。)

快速测试示例

Declare @D1 datetime ='2017-03-13 11:00:02'
Declare @D2 datetime ='2017-03-30 19:53:59'

Select Count(*)/60.0/24.0
 From  (
        Select Top (DateDiff(MINUTE,@D1,@D2)) 
               D=DateAdd(MINUTE,-1+Row_Number() Over (Order By (Select NULL)),@D1) 
         From  master..spt_values N1,master..spt_values N2
       ) N
 Where Datename(WeekDay,D) Not In ('Saturday','Sunday')
   and D Not In ( '2016-01-01' -- New Year's Day
                 ,'2016-01-18' -- Martin Luther King, Jr,
                 ,'2016-02-15' -- Washington''s Birthday
                 ,'2016-03-25' -- Good Friday
                 ,'2016-05-30' -- Memorial Day
                 ,'2016-07-04' -- Independence Day
                 ,'2016-09-05' -- Labor Day
                 ,'2016-11-24' -- Thanksgiving
                 ,'2016-11-25' -- Black Friday
                 ,'2016-12-26' -- Christmas Day
                )

<强>返回

13.370138875
  

编辑 - 如果感兴趣并且只是为了好玩 - 两个功能TVF和SVF

表格值函数

CREATE FUNCTION [dbo].[MyFunctionTV] (@D1 datetime,@D2 datetime)
Returns Table 
As
Return (  

Select Value = Count(*)/60.0/24.0
 From  (
         Select Top (DateDiff(MINUTE,@D1,@D2)) 
                D=DateAdd(MINUTE,-1+Row_Number() Over (Order By (Select NULL)),@D1) 
          From  master..spt_values N1,master..spt_values N2
       ) N
 Where Datename(WeekDay,D) Not In ('Saturday','Sunday')
   and D Not In ( '2016-01-01' -- New Year's Day
                 ,'2016-01-18' -- Martin Luther King, Jr,
                 ,'2016-02-15' -- Washington''s Birthday
                 ,'2016-03-25' -- Good Friday
                 ,'2016-05-30' -- Memorial Day
                 ,'2016-07-04' -- Independence Day
                 ,'2016-09-05' -- Labor Day
                 ,'2016-11-24' -- Thanksgiving
                 ,'2016-11-25' -- Black Friday
                 ,'2016-12-26' -- Christmas Day
                )
)
-- Goal   : 13.370138875
-- Select * from [dbo].[MyFunctionTV]('2017-03-13 11:00:02','2017-03-30 19:53:59')

标量值函数

CREATE FUNCTION [dbo].[MyFunctionSV] (@D1 datetime,@D2 datetime)
Returns float
As
Begin
Return (  

Select Count(*)/60.0/24.0
 From  (
         Select Top (DateDiff(MINUTE,@D1,@D2)) 
                D=DateAdd(MINUTE,-1+Row_Number() Over (Order By (Select NULL)),@D1) 
          From  master..spt_values N1,master..spt_values N2
       ) N
 Where Datename(WeekDay,D) Not In ('Saturday','Sunday')
   and D Not In ( '2016-01-01' -- New Year's Day
                 ,'2016-01-18' -- Martin Luther King, Jr,
                 ,'2016-02-15' -- Washington''s Birthday
                 ,'2016-03-25' -- Good Friday
                 ,'2016-05-30' -- Memorial Day
                 ,'2016-07-04' -- Independence Day
                 ,'2016-09-05' -- Labor Day
                 ,'2016-11-24' -- Thanksgiving
                 ,'2016-11-25' -- Black Friday
                 ,'2016-12-26' -- Christmas Day
                )
)
End
-- Goal   : 13.370138875
-- Select [dbo].[MyFunctionSV]('2017-03-13 11:00:02','2017-03-30 19:53:59')