if exists (select * from dbo.sysobjects where id = object_id(N'[tb_Holiday]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
drop table [tb_Holiday]
GO--定义节假日表
CREATE TABLE tb_Holiday(
HDate smalldatetime primary key clustered, --节假日期
Name nvarchar(50) not null)             --假日名称
GOif exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[f_WorkDay]') and xtype in (N'FN', N'IF', N'TF'))
drop function [dbo].[f_WorkDay]
GO--计算两个日期之间的工作天数
CREATE FUNCTION f_WorkDay(
@dt_begin datetime,  --计算的开始日期
@dt_end  datetime   --计算的结束日期
)RETURNS int
AS
BEGIN
IF @dt_begin>@dt_end
RETURN(DATEDIFF(Day,@dt_begin,@dt_end)
+1-(
SELECT COUNT(*) FROM tb_Holiday
WHERE HDate BETWEEN @dt_begin AND @dt_end))
RETURN(-(DATEDIFF(Day,@dt_end,@dt_begin)
+1-(
SELECT COUNT(*) FROM tb_Holiday
WHERE HDate BETWEEN @dt_end AND @dt_begin)))
END
GOif exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[f_WorkDayADD]') and xtype in (N'FN', N'IF', N'TF'))
drop function [dbo].[f_WorkDayADD]
GO--在指定日期上增加工作天数
CREATE FUNCTION f_WorkDayADD(
@date    datetime,  --基础日期
@workday int       --要增加的工作日数
)RETURNS datetime
AS
BEGIN
IF @workday>0
WHILE @workday>0
SELECT @date=@date+@workday,@workday=count(*)
FROM tb_Holiday
WHERE HDate BETWEEN @date AND @date+@workday
ELSE
WHILE @workday<0
SELECT @date=@date+@workday,@workday=-count(*)
FROM tb_Holiday
WHERE HDate BETWEEN @date AND @date+@workday
RETURN(@date)
END

解决方案 »

  1.   


    if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[f_WorkDayADD]') and xtype in (N'FN', N'IF', N'TF'))
    drop function [dbo].[f_WorkDayADD]
    GO--在指定日期上,增加指定工作天数后的日期
    CREATE FUNCTION f_WorkDayADD(
    @date    datetime,  --基础日期
    @workday int       --要增加的工作日数
    )RETURNS datetime
    AS
    BEGIN
    DECLARE @bz int
    --增加整周的天数
    SELECT @bz=CASE WHEN @workday<0 THEN -1 ELSE 1 END
    ,@date=DATEADD(Week,@workday/5,@date)
    ,@workday=@workday%5
    --增加不是整周的工作天数
    WHILE @workday<>0 
    SELECT @date=DATEADD(Day,@bz,@date),
    @workday=CASE WHEN (@@DATEFIRST+DATEPART(Weekday,@date)-1)%7 BETWEEN 1 AND 5
    THEN @workday-@bz ELSE @workday END
    --避免处理后的日期停留在非工作日上
    WHILE (@@DATEFIRST+DATEPART(Weekday,@date)-1)%7 in(0,6) 
    SET @date=DATEADD(Day,@bz,@date)
    RETURN(@date)
    END
      

  2.   

    if exists (select * from dbo.sysobjects where id = object_id(N'[dbo].[f_WorkDayADD]') and xtype in (N'FN', N'IF', N'TF')) 
    drop function [dbo].[f_WorkDayADD] 
    GO --在指定日期上,增加指定工作天数后的日期 
    CREATE FUNCTION f_WorkDayADD( 
    @date    datetime,  --基础日期 
    @workday int       --要增加的工作日数 
    )RETURNS datetime 
    AS 
    BEGIN 
    DECLARE @bz int 
    --增加整周的天数 
    SELECT @bz=CASE WHEN @workday <0 THEN -1 ELSE 1 END 
    ,@date=DATEADD(Week,@workday/5,@date) 
    ,@workday=@workday%5 
    --增加不是整周的工作天数 
    WHILE @workday <> 0  
    SELECT @date=DATEADD(Day,@bz,@date), 
    @workday=CASE WHEN (@@DATEFIRST+DATEPART(Weekday,@date)-1)%7 BETWEEN 1 AND 5 
    THEN @workday-@bz ELSE @workday END 
    --避免处理后的日期停留在非工作日上 
    WHILE (@@DATEFIRST+DATEPART(Weekday,@date)-1)%7 in(0,6)  
    SET @date=DATEADD(Day,@bz,@date) 
    RETURN(@date) 
    END 
      

  3.   

    但是程序中没有出现table1.holidays呀?
    法定假日保存在table1.holidays里面。
      

  4.   

    生成的日期..再跟你的holidays比较就好了.用not exists跟not in
      

  5.   

    --定义节假日表
    CREATE TABLE tb_Holiday(
    HDate smalldatetime primary key clustered, --节假日期
    Name nvarchar(50) not null)             --假日名称
    GO这儿你作相应的修改呀
      

  6.   

    --比如function fnA("2008-03-19", 5),那么应该返回 2008-03-26,因为中间隔了一个周末(2天)。 
    --如果假设有一个法定假日在2008-03-26(保存在table1.holidays里面),那么应该返回的是 2008-03-27 if exists (select * from dbo.sysobjects where id = object_id(N'[table1]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
    drop table [table1]
    GO--定义节假日表
    CREATE TABLE table1(
    holidays smalldatetime primary key clustered, --节假日期
    Name nvarchar(50) not null)             --假日名称
    GO
    insert table1 select '2008-03-26','wow'go
    --在指定日期上,增加指定工作天数后的日期 
    CREATE FUNCTION f_WorkDayADD( 
    @date    datetime,  --基础日期 
    @workday int       --要增加的工作日数 
    )RETURNS datetime 
    AS 
    BEGIN 
    DECLARE @bz int 
    --增加整周的天数 
    SELECT @bz=CASE WHEN @workday <0 THEN -1 ELSE 1 END 
    ,@date=DATEADD(Week,@workday/5,@date) 
    ,@workday=@workday%5 
    --增加不是整周的工作天数 
    WHILE @workday <> 0  
    SELECT @date=DATEADD(Day,@bz,@date), 
    @workday=CASE WHEN (@@DATEFIRST+DATEPART(Weekday,@date)-1)%7 BETWEEN 1 AND 5 
    THEN @workday-@bz ELSE @workday END 
    --避免处理后的日期停留在非工作日上 
    WHILE (@@DATEFIRST+DATEPART(Weekday,@date)-1)%7 in(0,6)  
    SET @date=DATEADD(Day,@bz,@date) 
        WHILE exists(select 1 from table1 where datediff(d,holidays,@date) =0 )
            SET @date=DATEADD(Day,1,@date)
    RETURN(@date) 
    END 
    go
    select  dbo.f_WorkDayADD('2008-03-19', 5)
    drop function f_WorkDayADD
    drop table table1/*
    ------------------------------------------------------ 
    2008-03-27 00:00:00.000(所影响的行数为 1 行)
    */
      

  7.   

    上面的结果不对,如果把insert table1 select '2008-03-26','wow'
    改成
    insert table1 select '2008-03-25','wow'就会返回 2008-03-26
      

  8.   

    if exists (select * from dbo.sysobjects where id = object_id(N'[table1]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
    drop table [table1]
    GO--定义节假日表
    CREATE TABLE table1(
    holidays smalldatetime primary key clustered, --节假日期
    Name nvarchar(50) not null)             --假日名称
    GO
    insert table1 select '2008-03-25','wow'go
    --在指定日期上,增加指定工作天数后的日期 
    CREATE FUNCTION f_WorkDayADD( 
    @date    datetime,  --基础日期 
    @workday int       --要增加的工作日数 
    )RETURNS datetime 
    AS 
    BEGIN 
        DECLARE @bz int 
        --增加整周的天数 
        SELECT @bz=CASE WHEN @workday <0 THEN -1 ELSE 1 END 
        ,@date=DATEADD(Week,@workday/5,@date) 
        ,@workday=@workday%5 
        --增加不是整周的工作天数 
        WHILE @workday <> 0  
            SELECT @date=DATEADD(Day,@bz,@date), 
            @workday=CASE WHEN (@@DATEFIRST+DATEPART(Weekday,@date)-1)%7 BETWEEN 1 AND 5 
            THEN @workday-@bz ELSE @workday END 
            --避免处理后的日期停留在非工作日上 
        WHILE (@@DATEFIRST+DATEPART(Weekday,@date)-1)%7 in(0,6)  
            SET @date=DATEADD(Day,@bz,@date) 
        WHILE exists(select 1 from table1 where datediff(d,holidays,@date) =0 )
            SET @date=DATEADD(Day,1,@date)
    RETURN(@date) 
    END 
    go
    select  dbo.f_WorkDayADD('2008-03-19', 5)
    drop function f_WorkDayADD
    drop table table1/*
                                                           
    ------------------------------------------------------ 
    2008-03-26 00:00:00.000(所影响的行数为 1 行)
    */
      

  9.   

    这不是你想要的结果 吗?--比如function fnA("2008-03-19", 5),那么应该返回 2008-03-26,因为中间隔了一个周末(2天)。 
    --如果假设有一个法定假日在2008-03-26(保存在table1.holidays里面),那么应该返回的是 2008-03-27 这不是你的原话吗
      

  10.   

    需要写一个函数,接受2个参数(一个日期,一个整型),返回一个日期 
    返回的日期是参数日期加上整形数,但不包含周六,周日,也不包含法定假日(保存在table1.holidays里面) 貌似没法搞.中国的法定假日是变的.
    除非你把所有的法定假日放一表存起来,然后做相关判断才行.
      

  11.   


    --如果假设有一个法定假日在2008-03-26(保存在table1.holidays里面),那么应该返回的是 2008-03-27如果法定假日在25号,那也应该返回2008-03-27呀,为什么会返回26呢?如果给参数('2008-03-19', 5)那么应该这样计算: 20, 21, 24, 26, 27
    所以也应该返回27(22,23 是周末,25是法定假日)
      

  12.   

    if exists (select * from dbo.sysobjects where id = object_id(N'[table1]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
    drop table [table1]
    GO--定义节假日表
    CREATE TABLE table1(
    holidays smalldatetime primary key clustered, --节假日期
    Name nvarchar(50) not null)             --假日名称
    GO
    insert table1 select '2008-03-25','wow'go
    --在指定日期上,增加指定工作天数后的日期 
    CREATE FUNCTION f_WorkDayADD( 
    @date    datetime,  --基础日期 
    @workday int       --要增加的工作日数 
    )RETURNS datetime 
    AS 
    BEGIN 
        DECLARE @bz int 
    declare @olddate datetime
        set @olddate = @date
        --增加整周的天数 
        SELECT @bz=CASE WHEN @workday <0 THEN -1 ELSE 1 END 
        ,@date=DATEADD(Week,@workday/5,@date) 
        ,@workday=@workday%5 
        --增加不是整周的工作天数 
        WHILE @workday <> 0  
            SELECT @date=DATEADD(Day,@bz,@date), 
            @workday=CASE WHEN (@@DATEFIRST+DATEPART(Weekday,@date)-1)%7 BETWEEN 1 AND 5 
            THEN @workday-@bz ELSE @workday END 
            --避免处理后的日期停留在非工作日上 
        WHILE (@@DATEFIRST+DATEPART(Weekday,@date)-1)%7 in(0,6)  
            SET @date=DATEADD(Day,@bz,@date) 
    --    WHILE exists(select 1 from table1 where datediff(d,holidays,@date) =0 )
    --        SET @date=DATEADD(Day,1,@date)
            select @bz = count(1) from table1 where holidays between  @olddate and @date 
        SET @date=DATEADD(Day,@bz,@date)
    RETURN(@date) 
    END 
    go
    select  dbo.f_WorkDayADD('2008-03-19', 5)
    drop function f_WorkDayADD
    drop table table1
    /*
    ------------------------------------------------------ 
    2008-03-27 00:00:00.000(所影响的行数为 1 行)
    */
      

  13.   

    if exists (select * from dbo.sysobjects where id = object_id(N'[table1]') and OBJECTPROPERTY(id, N'IsUserTable') = 1)
    drop table [table1]
    GO--定义节假日表
    CREATE TABLE table1(
    holidays smalldatetime primary key clustered, --节假日期
    Name nvarchar(50) not null)             --假日名称
    GO
    insert table1 select '2008-03-25','wow'go
    --在指定日期上,增加指定工作天数后的日期 
    CREATE FUNCTION f_WorkDayADD( 
    @date    datetime,  --基础日期 
    @workday int       --要增加的工作日数 
    )RETURNS datetime 
    AS 
    BEGIN 
        DECLARE @bz int 
    declare @olddate datetime
        set @olddate = @date
        --增加整周的天数 
        SELECT @bz=CASE WHEN @workday <0 THEN -1 ELSE 1 END 
        ,@date=DATEADD(Week,@workday/5,@date) 
        ,@workday=@workday%5 
        --增加不是整周的工作天数 
        WHILE @workday <> 0  
            SELECT @date=DATEADD(Day,@bz,@date), 
            @workday=CASE WHEN (@@DATEFIRST+DATEPART(Weekday,@date)-1)%7 BETWEEN 1 AND 5 
            THEN @workday-@bz ELSE @workday END 
        --避免处理后的日期停留在非工作日上 
        WHILE (@@DATEFIRST+DATEPART(Weekday,@date)-1)%7 in(0,6)  
            SET @date=DATEADD(Day,@bz,@date) 
        --加上这段时间内自定义的节日天数
        select @bz = count(1) from table1 where holidays between  @olddate and @date 
        SET @date=DATEADD(Day,@bz,@date)
        -- 看加上自定义节日后是否是周末
        WHILE (@@DATEFIRST+DATEPART(Weekday,@date)-1)%7 in(0,6) or exists(select 1from table1 where holidays = @date)
            SET @date=DATEADD(Day,1,@date)
    RETURN(@date) 
    END 
    go
    select  dbo.f_WorkDayADD('2008-03-19', 5)
    drop function f_WorkDayADD
    drop table table1
    /*
    ------------------------------------------------------ 
    2008-03-27 00:00:00.000(所影响的行数为 1 行)
    */
    注意 法定与自定义的节日表不同重复