使 UDF 独立于 DATEFIRST 设置
Posted
技术标签:
【中文标题】使 UDF 独立于 DATEFIRST 设置【英文标题】:Make a UDF independent of DATEFIRST setting 【发布时间】:2011-05-12 15:52:23 【问题描述】:在 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
【问题讨论】:
【参考方案1】:IF (@@DATEFIRST + DATEPART(DW, @toDate)) % 7 not in (0,1)
应该适用于我认为所有可能的 DATEFIRST
值。
我可能会为此使用辅助日历表,而不是循环 UDF。
【讨论】:
DATEPART 返回的值取决于 SET DATEFIRST 的当前设置。改变一个,你改变另一个。 @Philip。同意。这就是添加@@DATEFIRST
的原因。
完美,效果极佳。关于。日历查找解决方案,我们使用它来计算公共假期、非标准公司假期等,并在适当的情况下将其与通用工作日功能相结合。【参考方案2】:
如何使用工作日名称(不受@@datefirst
影响):
if left(datename(weekday, @toDate), 3) in ('Sat', 'Sun')
...
正如马丁指出的那样,需要注意的是;
SET LANGUAGE Italian
select datename(weekday, GETDATE())
>> giovedì
【讨论】:
但我认为它们与语言有关,不是吗? 对不起,我现在实际上已经阅读了这个问题,看看你是从哪里来的!希望至少所有环境都使用相同的语言。 我喜欢这种方法,这可能是我最好的选择 - LANGUAGE 变化小于 DATEFIRST,至少。但是,当我的目标是在任何服务器上使用此功能而无需根据环境对其进行定制时,它仍然是一个潜在的“陷阱”。另外,我不能在 UDF 中使用SET LANGUAGE
,就像禁止使用 SET DATEFIRST
一样。以上是关于使 UDF 独立于 DATEFIRST 设置的主要内容,如果未能解决你的问题,请参考以下文章