2017-04-19 74 views
3

我有一个函数应该计算在给定日期之前或之后的x个工作日(不包括周末和假日)。我可以在迭代中添加额外的步骤吗?

的问题是,当最后一天适逢周末或工作日,不添加额外的迭代...

SELECT afidb.dbo.AddBusinessDays(-21,'11/08/2016') 

上面应该返回2016-10-7,但返回2016-10-10 。 10月10日是假期,并且是周末前2天。

我认为这是因为在最后一次迭代时,@bdays = 0因此它退出并且不会添加额外的步骤。

我在这里错了,还是有另一个问题呢?

ALTER FUNCTION [dbo].[Addbusinessdays] (
    @bDays INT -- number of business days to add sub. 
    ,@d DATETIME -- variable to hold the date you want to add or sub days to 
    ) 
RETURNS DATE 
AS 
BEGIN 
    DECLARE @nDate DATETIME -- the working date 
     ,@addsub INT -- factor for add or sub 

    SET @ndate = @d 

    IF @bdays > 0 
     SET @addsub = 1 
    ELSE 
     SET @addsub = - 1 

    WHILE @bdays <> 0 -- Keep adding/subtracting a day until @bdays becomes 0 
    BEGIN 
     -- incr or decr @ndate 
     SELECT @bdays = CASE 
       WHEN (@@datefirst + Datepart(weekday, @ndate)) % 7 IN (0 ,1) -- ignore if it is Sat or Sunday 
        THEN CASE 
          WHEN @bDays = 0 
           THEN @bdays + 1 * @addsub 
          ELSE @bDays 
          END 
       WHEN (
         SELECT Count(*) 
         FROM dbo.tblholidays 
         WHERE holidaydate = @nDate 
         ) > 0 
        -- ignore if it is in the holiday table 
        THEN CASE 
          WHEN @bDays = 0 
           THEN @bdays + 1 * @addsub 
          ELSE @bDays 
          END 
       ELSE @bdays - 1 * @addsub -- incr or decr @ndate 
       END 

     SET @ndate = Dateadd(day, 1 * @addsub, @ndate) 
    END 

    RETURN Cast(@nDate AS DATE) 
END 
+0

提示:请参见[sign()](https://docs.microsoft.com/zh-cn/sql/t-sql/functions/sign-transact-sql)。当检查一行或多行的存在时,使用['EXISTS'](https://msdn.microsoft.com/en-us/library/ms188336.aspx)而不是确切地获得['COUNT '](https://msdn.microsoft.com/en-us/library/ms175997.aspx),然后检查它是否大于零。 – HABO

回答

1

您需要在while循环结束时进行额外检查,以确保您不会在非工作日登陆。在你SET @ndate = Dateadd(day,1 * @addsub,@ndate)之后,你必须再次检查@ndate。如果这是非营业日,则递增或递减@bdays,以便您再次进入循环。

相关问题