扣除节假日高效算法

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

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

None.gif CREATE     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 ( SMALLDATETIME CAST ( @YEAR   AS   CHAR ( 4 ))  +   ' -01-01 ' 120 )
None.gif        
SET   @END_DATE   =   DATEADD ( YEAR 1 @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 ( DAY 1 @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  ( @YEAR FLOOR ( 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  ( @YEAR FLOOR ( CONVERT ( FLOAT @THIS_DATE )),  @THIS_DATE DATENAME (WEEKDAY,  @THIS_DATE ))
None.gif            
END
None.gif            
SET   @THIS_DATE   =   DATEADD ( DAY 1 @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.gif ContractedBlock.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_Date 120 )   -- 去掉时间部分(防止传入的参数中有时间部分,影响处理)
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天前的数据

希望对大家有帮助

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值