首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > 其他数据库 >

function范例1:计算工作时间(开始时间,结束时间)

2012-07-25 
function实例1:计算工作时间(开始时间,结束时间)场景:信审系统需要开发一个function,用于计算每个流程节点

function实例1:计算工作时间(开始时间,结束时间)
场景:信审系统需要开发一个function,用于计算每个流程节点占用的时间,以判断审核是否超时,超时相关参数如下:
1、每日工作时间 A:24小时 B:工作时间 ;
2、是否包含节假日: A 包含 B不包含
3、时间限制(单位/小时):输入项如24;

方案如下:
1、默认周末为休息日,其它特殊的工作日和假日需要记录在数据库中,建立一个工作日配置表 config_workday
(workday_config_id 主键
workday_type  工作日类型(字典,典型值如 0 休息日 1工作日)
date  日期(年月日,典型值如2011-07-20)
demo  说明、创建人、创建时间等5个字段
)
2、新建function:
计算起止时间之间花费的工作时间callWorkTime(v_start_time VARCHAR2, 开始时间
                                        v_end_time   VARCHAR2, 结束时间
                                        v_is_include_holiday VARCHAR2,休息日是否计算在内
                                        v_hours_for_day VARCHAR2) 每日工作时间
实现如下:
create or replace function callWorkTime(v_start_time VARCHAR2,
                                        v_end_time   VARCHAR2,
                                        v_is_include_holiday VARCHAR2,
                                        v_hours_for_day VARCHAR2)
  return NUMBER is
  v_total        NUMBER := 0;
  v_zhongjian    NUMBER := 0;
  v_current_time VARCHAR2(30) := v_start_time;
  v_xinqi        NUMBER := 1;
  v_count        NUMBER := 0;
  v_is_holiday   NUMBER := 0;
  v_start_work_hour VARCHAR2(10) :=' 09:00:00';
  v_end_work_hour VARCHAR2(10) :=' 17:00:00';
BEGIN
  --设置上下班时间
  IF(v_hours_for_day ='24')  THEN
      v_start_work_hour :=' 00:00:00';
      v_end_work_hour :=' 23:59:59';
  END IF;
  WHILE v_current_time < v_end_time LOOP
    IF (v_is_include_holiday = 0) THEN
        ---若统计时间不包含节假日,查出星期几,判断是否休息日
        SELECT to_number(to_char(to_date(v_current_time,'YYYY-MM-DD HH24:MI:SS'),'d'))
          INTO v_xinqi
          FROM DUAL;
        --如果是星期六(7)、日(1)
        IF (v_xinqi = 7 OR v_xinqi = 1) THEN
           SELECT COUNT(*) INTO v_count FROM tc_config_workday t WHERE t.work_day = substr(v_current_time,0,10) AND t.workday_type = '1';
              IF  v_count > 0 THEN
                  v_is_holiday :=0;
              ELSE
                  v_is_holiday :=1;
              END IF;
         
        -- 如果是星期一~五(2~6)
        ELSE     
            SELECT COUNT(*) INTO v_count FROM tc_config_workday t WHERE t.work_day = substr(v_current_time,0,10) AND t.workday_type = '0';
            IF  v_count> 0 THEN
                v_is_holiday :=1;
            ELSE
                v_is_holiday :=0;
            END IF;
        END IF;
    END IF;
    IF (v_is_holiday = 1) THEN
      --如果是被计算的时间是休息日的话,把开始时间算成下一个工作日
      SELECT TO_CHAR(to_date(substr(v_current_time, 0, 10), 'YYYY-MM-DD') + 1,'YYYY-MM-DD')||v_start_work_hour
        INTO v_current_time
        FROM DUAL;
    ELSE
      --如果v_current_time和v_end_time不是同一天,v_current_time当天汇总后往后推一天
        IF (substr(v_current_time, 0, 10) < substr(v_end_time, 0, 10)) THEN
            SELECT to_date(substr(v_current_time, 0, 10)||v_end_work_hour,
                            'YYYY-MM-DD HH24:MI:SS') -
                    to_date(v_current_time, 'YYYY-MM-DD HH24:MI:SS')
              INTO v_zhongjian
              FROM dual;
            v_total := v_total + v_zhongjian;
            SELECT TO_CHAR(to_date(substr(v_current_time, 0, 10), 'YYYY-MM-DD') + 1,
                            'YYYY-MM-DD')||v_start_work_hour
              INTO v_current_time
              FROM dual;
        ELSE
          --如果v_current_time和v_end_time是同一天,汇总后退出循环
            SELECT to_date(v_end_time, 'YYYY-MM-DD HH24:MI:SS') -
                   to_date(v_current_time, 'YYYY-MM-DD HH24:MI:SS')
              INTO v_zhongjian
              FROM dual;
            v_total := v_total + v_zhongjian;
            EXIT;
        END IF;
    END IF;
 
  END LOOP;

  RETURN v_total * 24;
END callWorkTime;

3、将每个流程节点的时间做sum,超出时间限制即为超时:

热点排行