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

用oracle 写一个函数 函数有2个参数,一个是工作日期,一个是整型表示几天。该如何解决

2012-06-06 
用oracle 写一个函数 函数有2个参数,一个是工作日期,一个是整型表示几天。写一个函数,要求返回当天工作日期

用oracle 写一个函数 函数有2个参数,一个是工作日期,一个是整型表示几天。
写一个函数,要求返回当天工作日期几天后的工作日期,举例:假如今天是星期一,3天后的工作日期是星期四的工作日期。假如今天是星期五,那么3天后的工作日期是星期三的工作日期。把星期六和星期天去掉了。假如今天是星期六,3天后的工作日期就是星期三的工作日期。

[解决办法]

SQL code
-- 请参考:create or replace function fc_ncdate(i_date_id number:=to_number(to_date(sysdate-1,'YYYYMMDD')), i_ndays number:=5)  return  tabCdateis/***************************************************  **     功能:根据传入的参数i_date_id是否是工作日或非工作日  **           (周六、日视为非工作日)来求最近N(参数i_ndays控制)个工作日或非工作日  **   创建者:罗友谋  ** 创建时间:2012.02.22  ****************************************************/  Result tabcdate := tabcdate();  v_ndays number(18,0);  v_is_weekday1 number(1,0); -- 标记传入的参数 是否是周六、日  v_is_weekday2 number(1,0); -- 标记循环过程中的日期变量是否是周六、日  v_date_id DATE;  v_loops number(18,0);begin  SELECT decode(to_char(to_date(i_date_id,'YYYYMMDD'),'d'),'1',1,'7',1,0) as is_weekday INTO v_is_weekday1 FROM dual;  v_loops := i_ndays-1;  Result := tabcdate();  Result.extend;  Result(Result.count) := CDATE(NULL);  Result(Result.count).date_id := i_date_id;  v_date_id := to_date(i_date_id,'YYYYMMDD')-1;  WHILE v_loops > 0 LOOP    SELECT decode(to_char(v_date_id,'d'),'1',1,'7',1,0) as is_weekday INTO v_is_weekday2 FROM dual;    IF v_is_weekday1<>v_is_weekday2 THEN      v_date_id := v_date_id-1;    ELSE    BEGIN      Result.extend;      Result(Result.count) := CDATE(NULL);      Result(Result.count).date_id := to_number(to_char(v_date_id,'YYYYMMDD'));      v_loops := v_loops - 1;      v_date_id := v_date_id-1;    END;    END IF;  END LOOP;   return(Result);end fc_ncdate;
[解决办法]
SQL code
create or replace function fc_nworkday(  i_date date:=TRUNC(SYSDATE),  -- 你要输入的日期,默认值为当天0点  i_ndays number:=1             -- 你要查询N个工作日后的日期,N默认值为1)  return  dateis/***************************************************  **     功能:根据传入的参数i_date来求N(参数i_ndays控制)个工作日后的日期  **   创建者:罗友谋  ** 创建时间:2012.02.22  ****************************************************/  v_loops number(18,0);  v_date DATE;begin  v_loops := TRUNC(i_ndays); -- 截断 i_ndays 参数的小数部分  v_date := i_date;  IF i_ndays >0 THEN -- 如果输入的i_ndays为正数  BEGIN    WHILE v_loops > 0 LOOP      IF TO_CHAR(v_date,'d') IN ('6') THEN -- 如果是星期五        v_date := v_date + 3;      ELSE        v_date := v_date + 1;      END IF;        v_loops := v_loops - 1;      END LOOP;  END;  ELSIF i_ndays = 0 THEN    v_date := i_date;  ELSE  BEGIN    WHILE v_loops < 0 LOOP      IF TO_CHAR(v_date,'d') IN ('2') THEN -- 如果是星期一        v_date := v_date - 3;      ELSE        v_date := v_date - 1;      END IF;        v_loops := v_loops + 1;      END LOOP;  END;  END IF;  RETURN v_date;EXCEPTION  WHEN OTHERS THEN    NULL;END;/select to_char(fc_nworkday(sysdate,2),'YYYY-MM-DD HH24:MI:SS') from dual;
[解决办法]
SQL code
create or replace function get_work_date(i_date_in  in date,                                         i_date_cal in number) return date is  flag        boolean;  cal_day     number := abs(i_date_cal) + 1;  add_flag    number;  return_date date := i_date_in;  --today_excp exception;begin  flag := true;  if i_date_cal > 0 then    add_flag := 1;  else    add_flag := -1;  end if;  if cal_day = 0 then    flag := false;  else    while flag loop      if to_char(return_date + add_flag, 'd') in ('0', '7') then        return_date := return_date + add_flag;      else        return_date := return_date + add_flag;        cal_day     := cal_day - 1;        if cal_day <= 0 then          flag := false;        end if;      end if;    end loop;  end if;  return return_date;end;
[解决办法]
罗大师代码在修正一下,就可以包括周6,周天情况了




create or replace function fc_nworkday(
i_date date:=TRUNC(SYSDATE), -- 你要输入的日期,默认值为当天0点
i_ndays number:=1 -- 你要查询N个工作日后的日期,N默认值为1
)
return date
is
/***************************************************
** 功能:根据传入的参数i_date来求N(参数i_ndays控制)个工作日后的日期
** 创建者:罗友谋
** 创建时间:2012.02.22
****************************************************/
v_loops number(18,0);
v_date DATE;
begin
v_loops := TRUNC(i_ndays); -- 截断 i_ndays 参数的小数部分
v_date := i_date;
IF i_ndays >0 THEN -- 如果输入的i_ndays为正数
BEGIN
WHILE v_loops > 0 LOOP
IF TO_CHAR(v_date,'d') IN ('6') THEN -- 如果是星期五
v_date := v_date + 3;
ELSIF TO_CHAR(v_date,'d') IN ('7') THEN -- 如果是星期6
v_date := v_date + 2;
ELSIF TO_CHAR(v_date,'d') IN ('1') THEN -- 如果是星期天
v_date := v_date + 1;
ELSE
v_date := v_date + 1;
END IF;
v_loops := v_loops - 1;
END LOOP;
END;
ELSIF i_ndays = 0 THEN
v_date := i_date;
ELSE
BEGIN
WHILE v_loops < 0 LOOP
IF TO_CHAR(v_date,'d') IN ('2') THEN -- 如果是星期一
v_date := v_date - 3;
ELSIF TO_CHAR(v_date,'d') IN ('1') THEN -- 如果是星期天
v_date := v_date - 2;
ELSIF TO_CHAR(v_date,'d') IN ('7') THEN -- 如果是星期6
v_date := v_date - 1;
ELSE
v_date := v_date - 1;
END IF;
v_loops := v_loops + 1;
END LOOP;
END;
END IF;

RETURN v_date;
EXCEPTION
WHEN OTHERS THEN
NULL;
END;
/

热点排行