互联网服务数据库Informix

INFORMIX有关日期过界的解决的存储过程

Informix数据库由于其良好的动态扩展性,在各个行业得到了广泛的使用和认可,但Informix数据库自身也存在一点瑕疵(至少在IDS10上也有)就是Informix的日期处理问题,只要需要处理日期边界问题的时候,就有可能会出错!
  比如你使用 SELECT DATE("20000229")- 1 UNITS YEAR FROM dual ,从“2000/02/29”往前推算1年,而1999年,不是闰年,其2月份只有28天,这时就会报错(错误号1267)(出错信息:1267: The result of a datetime computation is out of range.)
  其它比如你从7月31日往前推1月,从1月31日/1月30日往后推1月,都会碰到日期边界处理出错的问题,给项目开发带来一些困扰!
  由于手头的项目需要进行日期的灵活计算,所以我考虑针对这些日期边界处理错误号(-1267、-1263、-1210)设置陷阱进行捕获,发现日期边界超限,则将日期往前推算,直到出现一个正常合法的日期为止!以下我改良的日期计算存储过程算法,可以按照“日”“月”“季”“半年”“年”灵活的向前向后推算日期。
  CREATE PROCEDURE p_random_date (
  v_random_date DATE,
  v_pass INT,
  v_mode VARCHAR(1) DEFAULT 'M'
  )
  RETURNING DATE;
  -- 参数 任意一天,经过月/天/年数,日期标度(月M,日D,年Y,半年H,季Q))
  -- return 任意一天经过N月/天/年后的对应日,若对应日不存在,则往前推
  DEFINE tmp_random_date DATE;
  DEFINE rtndate DATE;
  DEFINE v_pass1 INT;
  DEFINE esql, eisam INT;
  DEFINE etext VARCHAR(80);
  ON EXCEPTION SET esql, eisam, etext
  IF esql < 0 THEN
  RAISE EXCEPTION esql, eisam, etext;
  END IF
  END EXCEPTION
  LET tmp_random_date = v_random_date;
  LET rtndate = NULL;
  LET v_pass1 = 0;
  IF v_mode = 'H' THEN
  LET v_pass = v_pass*6;
  ELIF v_mode = 'Q' THEN
  LET v_pass = v_pass*3;
  END IF;
  {
  SET DEBUG FILE TO "random.log";
  TRACE ON;
  }
  WHILE 1 = 1
  ON EXCEPTION SET esql
  IF esql = -1267 THEN
  LET tmp_random_date = tmp_random_date -1;
  ELIF esql = -1263 THEN
  --处理ONLINE7.3x BUG: 2004/02/20 -14(或15) UNITS MONTH出错
  LET v_pass1 = v_pass1 + 1;
  ELIF esql = -1210 THEN
  --处理ONLINE7.3x BUG: 2004/02/20 -14(或15) UNITS MONTH出错
  LET v_pass1 = v_pass1 + 1;
  ELSE
  RAISE EXCEPTION esql;
  END IF;
  END EXCEPTION;
  IF v_mode = 'Y' THEN
  LET rtndate = tmp_random_date+v_pass UNITS YEAR;
  ELIF v_mode = 'D' THEN
  LET rtndate = tmp_random_date+v_pass UNITS DAY;
  ELSE -- v_mode IN ('M','H','Q')
  LET rtndate = (tmp_random_date+(v_pass-v_pass1) UNITS MONTH)+
  v_pass1 UNITS MONTH;
  END IF
  EXIT WHILE;
  END WHILE;
  RETURN rtndate;
  END PROCEDURE;
  调用举例如下:
  往前1个月 EXECUTE PROCEDURE p_random_date("20200229",-1,"M")
  往后60天 EXECUTE PROCEDURE p_random_date("20200229",60,"D")
  往前2 年 EXECUTE PROCEDURE p_random_date("20200229",-2,"Y")
参与0

0同行回答

“答”则兼济天下,请您为题主分忧!

提问者

jillme
CIO某大型银行

相关问题

相关资料

相关文章

问题状态

  • 发布时间:2010-11-02
  • 关注会员:0 人
  • 问题浏览:2382
  • X社区推广