sql server—sql函数似乎卡在循环中

to94eoyn  于 2021-08-13  发布在  Java
关注(0)|答案(3)|浏览(505)

我目前正在处理一个函数,它应该在作为参数发送给函数的日期前3个工作日返回。
我对sql中的函数有些陌生,我相信我的逻辑是合理的,但是我被卡住了。
我做了两张table。一个包含所有周末日期,一个包含所有假日日期。该函数的目的是接收一个日期,然后使用2个while循环计算提交日期之前的3个工作日,然后将新日期返回到我的select语句中。
以下是问题中的函数:

  1. FUNCTION [dbo].[lessThreeBD](@WORKING_DT DATE)
  2. RETURNS DATE
  3. AS
  4. BEGIN
  5. DECLARE @ThreeBD DATE
  6. DECLARE @COUNTER INT
  7. SET @COUNTER = 0
  8. WHILE @COUNTER < 4
  9. SET @ThreeBD = @WORKING_DT
  10. BEGIN
  11. 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'
  12. 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'
  13. BEGIN
  14. SET @WORKING_DT = DATEADD(DAY, -1, @WORKING_DT)
  15. END
  16. SET @WORKING_DT = DATEADD(DAY, -1, @WORKING_DT)
  17. SET @COUNTER = @COUNTER + 1
  18. SET @ThreeBD = @WORKING_DT
  19. END
  20. RETURN @ThreeBD
  21. END

但是,当我用一个日期测试它时,它似乎被锁定了:
测试线:

  1. SELECT DATABASE.dbo.lessThreeBD('2020-05-24') AS TESTING

这行应该返回20号。
知道我做错什么了吗?
记住假日和周末的餐桌都很好用。我已经测试了case语句,并且得到了每个case语句的预期结果。

zzwlnbp8

zzwlnbp81#

  1. WHILE @COUNTER < 4
  2. SET @ThreeBD = @WORKING_DT

等同于

  1. WHILE @COUNTER < 4
  2. BEGIN
  3. SET @ThreeBD = @WORKING_DT
  4. END

这是一个无限循环。
在tsql中始终使用begin/end with control flow语句。

  1. WHILE @COUNTER < 4
  2. BEGIN
  3. SET @ThreeBD = @WORKING_DT
  4. BEGIN
  5. . . .

也许除了常见的习语,比如

  1. if @@trancount > 0 rollback;
展开查看全部
1wnzp6jl

1wnzp6jl2#

我认为问题在于: WHILE @COUNTER < 4 SET @ThreeBD = @WORKING_DT BEGIN 此set命令正在无限循环中执行。

eivgtgni

eivgtgni3#

在修复了null问题和set不在begin中的问题之后,我不得不做了更多的修改,以使这项工作更准确。
最后一个功能如下所示,供任何想自用的人使用:

  1. FUNCTION [dbo].[lessThreeBD](@WORKING_DT DATE)
  2. RETURNS DATE
  3. AS
  4. BEGIN
  5. DECLARE @COUNTER INT
  6. SET @COUNTER = 0
  7. WHILE @COUNTER < 3
  8. BEGIN
  9. SET @WORKING_DT = DATEADD(DAY, -1, @WORKING_DT)
  10. SET @COUNTER = @COUNTER + 1
  11. WHILE (SELECT SQL_VARIANT_PROPERTY((SELECT TOP 1 HOL.DATE as CT from crmCAST.dbo.Holidays HOL where HOL.DATE = CAST(@WORKING_DT AS DATE)), 'BaseType')) IS NOT NULL
  12. OR (((DATEPART(DW, @WORKING_DT) - 1 ) + @@DATEFIRST ) % 7) IN (0,6)
  13. BEGIN
  14. SET @WORKING_DT = DATEADD(DAY, -1, @WORKING_DT)
  15. END
  16. END
  17. RETURN @WORKING_DT
  18. END

我可以用电脑把周末的table搬走 (((DATEPART(DW, @WORKING_DT) - 1 ) + @@DATEFIRST ) % 7) IN (0,6) 这将告诉我,如果日期是一个周末,所以你唯一需要的是一个表,其中列出了你的业务观察假期,这样你就可以有一个准确的3个工作日的回报。

展开查看全部

相关问题