查看: 9062|回复: 7

一个用于处理时间的函数

[复制链接]
论坛徽章:
90
生肖徽章:蛇
日期:2006-09-07 17:09:082011新春纪念徽章
日期:2011-01-25 15:42:332011新春纪念徽章
日期:2011-01-25 15:42:562011新春纪念徽章
日期:2011-02-18 11:43:34现任管理团队成员
日期:2011-05-07 01:45:082012新春纪念徽章
日期:2012-01-04 11:50:442012新春纪念徽章
日期:2012-02-13 15:12:092012新春纪念徽章
日期:2012-02-13 15:12:092012新春纪念徽章
日期:2012-02-13 15:12:092012新春纪念徽章
日期:2012-02-13 15:12:09
跳转到指定楼层
1#
发表于 2005-12-19 17:34 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
最近看到有人在做t_sql与pl/sql的转化, 问了些有关时间函数的处理, 在此, 仅对t_sql中的dateadd函数做说明, 这个函数在pl/sql中没有对应的函数, 但是oracle提供了其他的方法来处理, 这里, 本人写了一个同名的函数 dateadd用于方便移植使用, 其中用到的处理时间的方法在oracle中也很通用.

函数代码如下
create or replace function DATEADD( datepart  varchar2, num number, indate date ) return date is
  Result date;
  v_sql varchar2(1000);
  v_datepart varchar2(30);
  v_ms varchar2(13);
begin
  v_datepart := lower(datepart);
  /*
     Datepart         Abbreviations
     year             yy, y
     quarter          qq, q
     month            mm, m
     day              dd, d
     week             wk, w
     hour             hh, h
     minute           mi, n
     second           ss, s
     millisecond      ms
  */
  case
    when v_datepart in ('year','yy','y') then
      v_sql := 'select :1 + interval '''||num||''' year from dual';
    when v_datepart in ('quarter','qq','q') then
      v_sql := 'select :1 + (interval ''3'' month) * '||num||' from dual';
    when v_datepart in ('month','mm','m') then
      v_sql := 'select :1 + interval '''||num||''' month from dual';
    when v_datepart in ('week','wk','w') then
      v_sql := 'select :1 + (interval ''7'' day) * '||num||' from dual';
    when v_datepart in ('day','dd','d') then
      v_sql := 'select :1 + interval '''||num||''' day from dual';
    when v_datepart in ('hour','hh') then
      v_sql := 'select :1 + interval '''||num||''' hour from dual';
    when v_datepart in ('minute','mi','n') then
      v_sql := 'select :1 + interval '''||num||''' minute from dual';
    when v_datepart in ('second','ss','s') then
      v_sql := 'select :1 + interval '''||num||''' second from dual';
    when v_datepart in ('millisecond','ms') then
      v_ms := to_char(num/1000,'fm999999990.000');
      v_sql := 'select :1 + interval '''||v_ms||''' second(9,3) from dual';
    else
      RAISE_APPLICATION_ERROR(-20001, ''''||datepart||''' is not a recognized dateadd option.' );
  end case;
  
  execute immediate v_sql into Result using indate;
  
  return(Result);
  
EXCEPTION
  WHEN OTHERS THEN
    RAISE ;
   
end DATEADD;

函数中有一段注释, 是用来说明datepart的, 基本上和t_sql中的相同, 稍有修改

使用示例如下:
加三周时间:
SQL> select dateadd('w',3,sysdate), sysdate from dual;

DATEADD('W',3,SYSDATE) SYSDATE
---------------------- -----------
2006-1-9 17:16:29      2005-12-19

减一个季度时间:
SQL> select dateadd('q',-1,sysdate), sysdate from dual;

DATEADD('Q',-1,SYSDATE) SYSDATE
----------------------- -----------
2005-9-19 17:22:00      2005-12-19

大家随意点评吧
论坛徽章:
484
ITPUB北京香山2007年会纪念徽章
日期:2007-01-24 14:35:02ITPUB北京九华山庄2008年会纪念徽章
日期:2008-01-21 16:50:24ITPUB北京2009年会纪念徽章
日期:2009-02-09 11:42:452010新春纪念徽章
日期:2010-03-01 11:04:552010数据库技术大会纪念徽章
日期:2010-05-13 10:04:272010系统架构师大会纪念
日期:2010-09-04 13:35:54ITPUB9周年纪念徽章
日期:2010-10-08 09:28:512011新春纪念徽章
日期:2011-02-18 11:43:32ITPUB十周年纪念徽章
日期:2011-11-01 16:19:412012新春纪念徽章
日期:2012-01-04 11:49:54
2#
发表于 2005-12-19 19:07 | 只看该作者
jackywood出品,顶一下:)

使用道具 举报

回复
论坛徽章:
44
青年奥林匹克运动会-自行车
日期:2014-09-12 22:37:432012新春纪念徽章
日期:2012-02-13 15:12:092012新春纪念徽章
日期:2012-02-13 15:12:09咸鸭蛋
日期:2012-01-08 14:47:322012新春纪念徽章
日期:2012-01-04 11:50:44ITPUB十周年纪念徽章
日期:2011-11-01 16:21:15迷宫蛋
日期:2011-08-14 17:30:33双黄蛋
日期:2011-05-28 20:32:46紫蛋头
日期:2011-05-18 20:41:51现任管理团队成员
日期:2011-05-07 01:45:08
3#
发表于 2005-12-19 19:43 | 只看该作者
呵呵,我还以为是 一般的 SQL函数呢,嗯,好,暂时没发现什么问题。

使用道具 举报

回复
论坛徽章:
2
2010新春纪念徽章
日期:2010-03-01 11:19:50ITPUB十周年纪念徽章
日期:2011-11-01 16:20:28
4#
发表于 2005-12-19 20:02 | 只看该作者
这个好。。。 学习下。

使用道具 举报

回复
论坛徽章:
90
生肖徽章:蛇
日期:2006-09-07 17:09:082011新春纪念徽章
日期:2011-01-25 15:42:332011新春纪念徽章
日期:2011-01-25 15:42:562011新春纪念徽章
日期:2011-02-18 11:43:34现任管理团队成员
日期:2011-05-07 01:45:082012新春纪念徽章
日期:2012-01-04 11:50:442012新春纪念徽章
日期:2012-02-13 15:12:092012新春纪念徽章
日期:2012-02-13 15:12:092012新春纪念徽章
日期:2012-02-13 15:12:092012新春纪念徽章
日期:2012-02-13 15:12:09
5#
 楼主| 发表于 2005-12-19 23:07 | 只看该作者
最初由 lastwinner 发布
[B]jackywood出品,顶一下:) [/B]

谢谢友情顶

其实这个函数主要还是为了t_sql转pl/sql服务(即sql server 到 oracle 的移植), 另外还有一个sql server的函数 datediff, 还没有想到多好的办法, 容后再提供, 希望各位还能友情顶

使用道具 举报

回复
论坛徽章:
0
6#
发表于 2013-4-12 15:11 | 只看该作者
oracle 实现 sql server 中的dateadd, 支持

使用道具 举报

回复
论坛徽章:
0
7#
发表于 2015-3-5 10:30 | 只看该作者
只能加两位数吗? 加100天就报错了!
ora-01873:间隔的前导精度大小

使用道具 举报

回复
论坛徽章:
0
8#
发表于 2015-3-5 10:38 | 只看该作者
562845210 发表于 2015-3-5 10:30
只能加两位数吗? 加100天就报错了!
ora-01873:间隔的前导精度大小

改成这样就好啦!
v_sql := 'select :1 + interval '''||num||''' day(4) from dual';

day(4)就表示最大支持4位(9999),这一般情况可以满足啦!!!

使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 未成年人举报专区 
京ICP备16024965号-8  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表