我目前正在处理一个函数,它应该在作为参数发送给函数的日期前3个工作日返回。
我对sql中的函数有些陌生,我相信我的逻辑是合理的,但是我被卡住了。
我做了两张table。一个包含所有周末日期,一个包含所有假日日期。该函数的目的是接收一个日期,然后使用2个while循环计算提交日期之前的3个工作日,然后将新日期返回到我的select语句中。
以下是问题中的函数:
FUNCTION [dbo].[lessThreeBD](@WORKING_DT DATE)
RETURNS DATE
AS
BEGIN
DECLARE @ThreeBD DATE
DECLARE @COUNTER INT
SET @COUNTER = 0
WHILE @COUNTER < 4
SET @ThreeBD = @WORKING_DT
BEGIN
WHILE CASE WHEN (SELECT TOP 1 HOL.DATE from DATABASE.dbo.Holidays HOL where HOL.DATE = CAST(@WORKING_DT AS DATE)) IS NULL THEN 'NOT HOLIDAY' ELSE 'HOLIDAY' END = 'HOLIDAY'
OR CASE WHEN (SELECT TOP 1 WKND.DATE from DATABASE.dbo.Weekends WKND where WKND.DATE = CAST(@WORKING_DT AS DATE)) IS NULL THEN 'WEEKDAY' ELSE 'WEEKEND' END = 'WEEKEND'
BEGIN
SET @WORKING_DT = DATEADD(DAY, -1, @WORKING_DT)
END
SET @WORKING_DT = DATEADD(DAY, -1, @WORKING_DT)
SET @COUNTER = @COUNTER + 1
SET @ThreeBD = @WORKING_DT
END
RETURN @ThreeBD
END
但是,当我用一个日期测试它时,它似乎被锁定了:
测试线:
SELECT DATABASE.dbo.lessThreeBD('2020-05-24') AS TESTING
这行应该返回20号。
知道我做错什么了吗?
记住假日和周末的餐桌都很好用。我已经测试了case语句,并且得到了每个case语句的预期结果。
3条答案
按热度按时间zzwlnbp81#
这
等同于
这是一个无限循环。
在tsql中始终使用begin/end with control flow语句。
也许除了常见的习语,比如
1wnzp6jl2#
我认为问题在于:
WHILE @COUNTER < 4 SET @ThreeBD = @WORKING_DT BEGIN
此set命令正在无限循环中执行。eivgtgni3#
在修复了null问题和set不在begin中的问题之后,我不得不做了更多的修改,以使这项工作更准确。
最后一个功能如下所示,供任何想自用的人使用:
我可以用电脑把周末的table搬走
(((DATEPART(DW, @WORKING_DT) - 1 ) + @@DATEFIRST ) % 7) IN (0,6)
这将告诉我,如果日期是一个周末,所以你唯一需要的是一个表,其中列出了你的业务观察假期,这样你就可以有一个准确的3个工作日的回报。