扣除节假日高效算法

在日常开发中,有时需扣除节假日。本文分享了一套实用方法,包括表结构 ER 设计,将节假日表存储计算好的结果,日期换成‘整形日期’并建立索引提高判断速度,还给出存储过程和节假日扣除函数,可用于获取扣除节假日后的数据。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在日常开发中,有时候需要扣除节假日,本人实际开发中使用了一套比较好的办法与大家讨论.
表结构ER设计如下:
1.jpg

其中:节假日表,是存计算好的节假日结果.并且把日期换成"整形日期",建立索引提高判断速度,
只要节假日,变成,当晚就可以通过DTS最新计算节假日表,
存储过程如下:

None.gifCREATE   Procedure sp_holiday
None.gif    
@YEAR int
None.gif
AS
None.gif    
--产生节假日数据
None.gif
    --exec sp_holiday 2005
None.gif
    SET NOCOUNT ON
None.gif    
None.gif    
--判断是否需要计算
None.gif
    IF (SELECT SET_IS_REDO FROM TJ_SETTINGS WHERE SET_YEAR = @YEAR= 1
None.gif    
BEGIN
None.gif    
None.gif        
BEGIN TRAN
None.gif        
None.gif        
DELETE FROM TJ_HOLIDAY WHERE HOL_YEAR = @YEAR
None.gif        
DECLARE @SQL VARCHAR(100), @THIS_DATE SMALLDATETIME@BEGIN_DATE SMALLDATETIME@END_DATE SMALLDATETIME@HOL_NAME VARCHAR(50), @INDEX TINYINT@IS_WEEK TINYINT
None.gif        
--初始化双休日数据
None.gif
        CREATE TABLE #WEEK (WEEK_DAY TINYINT PRIMARY KEY NOT NULL, IS_WEEK TINYINT NULL)
None.gif        
SET @INDEX = 0
None.gif        
WHILE (@INDEX < 7)
None.gif        
BEGIN
None.gif            
SET @SQL = 'INSERT INTO #WEEK (WEEK_DAY, IS_WEEK) SELECT ' + CAST(@INDEX AS CHAR(1)) + ', WK_' + CAST(@INDEX AS CHAR(1)) + ' FROM TJ_WEEK WHERE WK_YEAR = ' + CAST(@YEAR AS CHAR(4))
None.gif            
EXEC(@SQL)
None.gif            
SET @INDEX = @INDEX + 1
None.gif        
END
None.gif        
--每一天判断
None.gif
        SET @BEGIN_DATE = CONVERT(SMALLDATETIMECAST(@YEAR AS CHAR(4)) + '-01-01'120)
None.gif        
SET @END_DATE = DATEADD(YEAR1@BEGIN_DATE)
None.gif        
SET @THIS_DATE = @BEGIN_DATE
None.gif        
WHILE (@THIS_DATE < @END_DATE)
None.gif        
BEGIN
None.gif            
--非节假日
None.gif
            IF EXISTS (SELECT * FROM TJ_NONFERIA WHERE NFR_YEAR = @YEAR AND NFR_DATE = @THIS_DATE)
None.gif            
begin
None.gif                
SET @THIS_DATE = DATEADD(DAY1@THIS_DATE)
None.gif                
CONTINUE
None.gif            
end
None.gif            
--节日
None.gif
            ELSE IF EXISTS (SELECT * FROM TJ_FERIA WHERE FER_YEAR = @YEAR AND FER_DATE = @THIS_DATE)
None.gif            
BEGIN
None.gif                
SELECT @HOL_NAME = FER_NAME FROM TJ_FERIA WHERE FER_YEAR = @YEAR AND FER_DATE = @THIS_DATE
None.gif                
INSERT INTO TJ_HOLIDAY (HOL_YEAR, HOL_DATE_INT, HOL_DATE, HOL_NAME) 
None.gif                
VALUES (@YEARFLOOR(CONVERT(FLOAT@THIS_DATE)), @THIS_DATE@HOL_NAME)
None.gif            
END
None.gif            
--休息日
None.gif
            ELSE
None.gif            
BEGIN
None.gif                
SELECT @IS_WEEK = IS_WEEK FROM #WEEK WHERE WEEK_DAY = (DATEPART(WEEKDAY, @THIS_DATE- 1)
None.gif                
IF (@IS_WEEK > 0)
None.gif                    
INSERT INTO TJ_HOLIDAY (HOL_YEAR, HOL_DATE_INT, HOL_DATE, HOL_NAME) 
None.gif                    
VALUES (@YEARFLOOR(CONVERT(FLOAT@THIS_DATE)), @THIS_DATEDATENAME(WEEKDAY, @THIS_DATE))
None.gif            
END
None.gif            
SET @THIS_DATE = DATEADD(DAY1@THIS_DATE)
None.gif        
END
None.gif        
None.gif        
--重新设置计算标记
None.gif
        UPDATE TJ_SETTINGS SET SET_IS_REDO = 0 WHERE SET_YEAR = @YEAR
None.gif        
None.gif        
IF @@ERROR = 0
None.gif            
COMMIT TRAN
None.gif        
ELSE 
None.gif            
ROLLBACK TRAN
None.gif        
None.gif        
DROP TABLE #WEEK
None.gif    
None.gif    
END
None.gif    
None.gif    
SET NOCOUNT OFF
None.gif
None.gif
GO
None.gif

ExpandedBlockStart.gifContractedBlock.gif/**//******************************************************************
InBlock.gif* 名称: 工作日重新
InBlock.gif* 作者: WANGYJ<edobnet@hotmail.com>
InBlock.gif* 时间: 2005-5-17
InBlock.gif*
InBlock.gif* -----------------------------------------------------------------
InBlock.gif* 版本        时间            作者        备注
InBlock.gif*
InBlock.gif* V1.00        2005-5-3    WANGYJ        创建
InBlock.gif* -----------------------------------------------------------------
ExpandedBlockEnd.gif*****************************************************************
*/

None.gif
create  Procedure sp_holiday_ALL
None.gif    
None.gif
AS
None.gif    
DECLARE my_cursor CURSOR for
None.gif    
select SET_YEAR from TJ_SETTINGS  where SET_IS_REDO = 1
None.gif    
DECLARE @year varchar(4)
None.gif    
None.gif    
open my_cursor
None.gif    
FETCH NEXT FROM my_cursor 
None.gif    
INTO @year
None.gif
WHILE @@FETCH_STATUS = 0
None.gif
BEGIN
None.gif    
exec risk.sp_holiday @year
None.gif  
None.gif    
FETCH NEXT FROM my_cursor 
None.gif    
INTO @year
None.gif       
None.gif
END
None.gif   
CLOSE my_cursor
None.gif   
DEALLOCATE my_cursor
None.gif
None.gif
GO
None.gif

节假日扣除函数如下:

None.gif
None.gif
None.gif
None.gif
CREATE    FUNCTION risk.CalcDay
None.gif(
None.gif    
@Diff smallint,        --差别值.正数为加,负数减
None.gif
    @D_Date datetime      --差别日期
None.gif
)
None.gif
RETURNS datetime
None.gif
AS
None.gif    
BEGIN
None.gif        
declare @ordDate datetime
None.gif        
set @ordDate = @D_Date
None.gif        
set @D_Date = convert(char(10), @D_Date120)  --去掉时间部分(防止传入的参数中有时间部分,影响处理)
None.gif
        if @Diff > 0
None.gif        
begin
None.gif            
while @Diff > 0
None.gif            
begin
None.gif                
select @D_Date = @D_Date + @Diff@Diff = count(*from TJ_HOLIDAY 
None.gif                
where HOL_DATE_INT > FLOOR(CONVERT(FLOAT@D_Date)) AND HOL_DATE_INT <= FLOOR(CONVERT(FLOAT@D_Date + @Diff))
None.gif            
end
None.gif        
end
None.gif        
else
None.gif        
begin
None.gif            
while @Diff < 0
None.gif            
begin
None.gif                
select @D_Date = @D_Date + @Diff@Diff =- count(*from TJ_HOLIDAY 
None.gif                
where HOL_DATE_INT < FLOOR(CONVERT(FLOAT@D_Date)) AND HOL_DATE_INT >= FLOOR(CONVERT(FLOAT@D_Date + @Diff))
None.gif            
end
None.gif        
end
None.gif    
set @D_Date = dateadd(hour,datepart(hour,@ordDate),@D_Date)
None.gif    
set @D_Date = dateadd(minute,datepart(minute,@ordDate),@D_Date)
None.gif    
set @D_Date = dateadd(second,datepart(second,@ordDate),@D_Date)
None.gif    
return(@D_Date)
None.gif    
END
None.gif
None.gif
None.gif
None.gif
None.gif
None.gif


这样就可以使用了,dbo.CaclDay(-5,getdate())就是扣除节假以后的5天前的数据

希望对大家有帮助

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值