大虾们, 以下是计算有效工作时间的几个函数这是本人前些天在论坛里发帖提问‘如何计算有效工作时间’后‘ssp2009’师兄为我解答的
但是我还是看不太懂 , 主要是不知道执行的步骤希望哪位前辈可一指点一下, 将一下过程附上步骤及详细讲解。非常感谢!在线求解/*关于上次的帖子请参阅
http://topic.csdn.net/u/20110905/15/5C9A82D9-6E81-4223-A9EA-95B42479589B.html
*/--工作日处理函数(标准节假日)
if 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
    DECLARE @workday int,@i int,@bz bit,@dt datetime
    IF @dt_begin>@dt_end
        SELECT @bz=1,@dt=@dt_begin,@dt_begin=@dt_end,@dt_end=@dt
    ELSE
        SET @bz=0
    SELECT @i=DATEDIFF(Day,@dt_begin,@dt_end)+1,
        @workday=@i/7*5,
        @dt_begin=DATEADD(Day,@i/7*7,@dt_begin)
    WHILE @dt_begin<=@dt_end
    BEGIN
        SELECT @workday=CASE 
            WHEN (@@DATEFIRST+DATEPART(Weekday,@dt_begin)-1)%7 BETWEEN 1 AND 5
            THEN @workday+1 ELSE @workday END,
            @dt_begin=@dt_begin+1
    END
    RETURN(CASE WHEN @bz=1 THEN -@workday ELSE @workday END)
END
GO/*=================================================================*/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--工作日处理函数(自定义节假日)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_WorkDay]') and xtype in (N'FN', N'IF', N'TF'))
    drop function [dbo].[f_WorkDay]
    GO
    【功能是如果函数f_WorkDay存在,则删除函数。{xtype in (N'FN', N'IF', N'TF')}说明:(类型为->标量函数|内嵌表函数|表函数)。
    SQL-SERVER的每个数据库内都有此系统表,它存放该数据库内创建的所有对象,如约束、默认值、日志、规则、存储过程等,每个对象在表中占一行。以下是此系统表的字段名称和相关说明。 Name,id,xtype,uid,status:分别是对象名,对象ID,对象类型,所有者对象的用户ID,对象状态。 对象类型(xtype)。可以是下列对象类型中的一种: C = CHECK 约束 D = 默认值或 DEFAULT 约束 F = FOREIGN KEY 约束 L = 日志 FN = 标量函数 IF = 内嵌表函数 P = 存储过程 PK = PRIMARY KEY 约束(类型是 K) RF = 复制筛选存储过程 S = 系统表 TF = 表函数 TR = 触发器 U = 用户表 UQ = UNIQUE 约束(类型是 K) V = 视图 X = 扩展存储过程 当xtype='U' and status>0代表是用户建立的表,对象名就是表名,对象ID就是表的ID值。 用: select * from misa.dbo.sysobjects where xtype='U'and status>0 就可以列出库misa中所有的用户建立的表名。 SELECT * FROM SYSOBJECTS WHERE PARENT_OBJ = OBJECT_ID( 'CS') AND XTYPE='TR' 列出表cs的所有属性,上面是trigger! 
     】--计算两个日期相差的工作天数
    CREATE FUNCTION f_WorkDay(
    @dt_begin datetime,  --计算的开始日期
    @dt_end  datetime    --计算的结束日期
    )RETURNS int
    AS
    BEGIN
        DECLARE @workday int,@i int,@bz bit,@dt datetime
        IF @dt_begin>@dt_end
            SELECT @bz=1,@dt=@dt_begin,@dt_begin=@dt_end,@dt_end=@dt --交换日期值
        ELSE
            SET @bz=0 --设置判别日期的 标志
        SELECT @i=DATEDIFF(Day,@dt_begin,@dt_end)+1,--设置参数  
            @workday=@i/7*5,
            @dt_begin=DATEADD(Day,@i/7*7,@dt_begin)
        WHILE @dt_begin<=@dt_end
        BEGIN
            SELECT @workday=CASE 
                WHEN (@@DATEFIRST+DATEPART(Weekday,@dt_begin)-1)%7 BETWEEN 1 AND 5             THEN @workday+1 ELSE @workday END,
                @dt_begin=@dt_begin+1
        END -- @@DATEFIRST 表示每周第一天
        RETURN(CASE WHEN @bz=1 THEN -@workday ELSE @workday END)--返回工作天数差
    END
    GO