使UDF独立于DATEFIRST设置

时间:2011-05-12 15:52:24

标签: sql-server user-defined-functions

在SO的答案的帮助下,我创建了一个SQL Server UDF(下面),它返回下一个工作日(工作日),给定日期和要添加的天数。

例如,如果日期是星期五,并且您想要添加一天,则返回值是下一个星期一的值。

这取决于假设@@DATEFIRST设置为1(星期一),因为我们无法在UDF中显式设置DATEFIRST

我的问题是我想在多个服务器上部署此功能,但它们具有不同的@@DATEFIRST设置,并且出于维护目的,在生产,测试和开发服务器之间我宁愿只使用一个无需工作的功能不得不担心使用哪个@@DATEFIRST设置。我已经花了太长时间想知道为什么我在不同的环境中得到不同的结果!

如果答案只是“使用存储过程”那么公平。 但是,如果有人可以建议如何重构以下内容以独立于DATEFIRST设置那么那将是很好的。重要的一行可能是if DatePart(dw, @toDate) not in (6, 7)...

功能定义:

CREATE FUNCTION [dbo].[fn_AddBusinessDays]
(   
@fromDate       datetime,
@daysToAdd      int
)
RETURNS datetime
AS
BEGIN   
DECLARE @toDate datetime
DECLARE @daysAdded integer

-- add the days, ignoring weekends (i.e. add working days)
set @daysAdded = 1
set @toDate = @fromDate

while @daysAdded <= @daysToAdd
begin
    -- add a day to the to date
    set @toDate = DateAdd(day, 1, @toDate)
    -- only move on a day if we've hit a week day
    if DatePart(dw, @toDate) not in (6, 7)
    begin
        set @daysAdded = @daysAdded + 1
    end
end

RETURN @toDate

END

2 个答案:

答案 0 :(得分:5)

IF (@@DATEFIRST + DATEPART(DW, @toDate)) % 7 not in (0,1)应该适用于我认为的所有DATEFIRST值。

我可能会使用Auxilliary Calendar表而不是循环UDF。

答案 1 :(得分:2)

如何使用工作日的名称(不受@@datefirst影响):

if left(datename(weekday, @toDate), 3) in ('Sat', 'Sun')
 ...

马丁指出,这是一个警告;

SET LANGUAGE Italian
select datename(weekday, GETDATE())

>> giovedì