实验14:操作日期的函数
常用的日期函数:
- SYSDATE:返回系统日期
- MONTHS_BETWEEN:返回两个日期间隔的月数
- ADD_MONTHS:在指定日期基础上加上相应的月数
- NEXT_DAY:返回某一日期的下一个指定日期
- LAST_DAY:返回指定日期当月最后一天的日期
- ROUND(date[,'fmt'])对日期进行指定格式的四舍五入操作。按照YEAR、MONTH、DAY等进行四舍五入。
- TRUNC(date[,'fmt'])对日期进行指定格式的截断操作。按照YEAR、MONTH、DAY等进行截断。
- EXTRACT:返回从日期类型中取出指定年、月、日
系统日期的操作
SYSDATE查当前数据库的时间
SQL> select sysdate from dual;
SYSDATE
--------------
25-6月 -13
查看当前日期的显示格式
SQL> col value for a20
SQL> select * from nls_session_parameters where parameter='NLS_DATE_FORMAT';
PARAMETER VALUE
------------------------------ --------------------
NLS_DATE_FORMAT DD-MON-RR
修改日期的显示格式
SQL> alter session set NLS_DATE_FORMAT='YYYY/MM/DD:HH24:MI:SS';
会话已更改。
SQL> SELECT SYSDATE FROM DUAL;
SYSDATE
-------------------
2013/06/25:16:25:03
查看系统时间,数据库本身没有时间,他有scn号,和我们的时间不同。
设定为默认格式
SQL> ALTER SESSION SET NLS_DATE_FORMAT='DD-MON-RR';
会话已更改。
SQL> SELECT SYSDATE FROM DUAL;
SYSDATE
--------------
25-6月 -13
再次查看,发现日期随着客户端的格式变化而变化。
日期的操作函数
两个日期的日间隔
SQL> select round(sysdate-hiredate) days,sysdate,hiredate from emp;
DAYS SYSDATE HIREDATE
---------- -------------- --------------
11879 25-6月 -13 17-12月-80
11814 25-6月 -13 20-2月 -81
11812 25-6月 -13 22-2月 -81
11773 25-6月 -13 02-4月 -81
11594 25-6月 -13 28-9月 -81
11744 25-6月 -13 01-5月 -81
11705 25-6月 -13 09-6月 -81
11544 25-6月 -13 17-11月-81
11614 25-6月 -13 08-9月 -81
11528 25-6月 -13 03-12月-81
11528 25-6月 -13 03-12月-81
11477 25-6月 -13 23-1月 -82
已选择12行。
两个日期时间相减的结果为天,往往带小数点,可以通过函数取整。
两个日期的月间隔
SQL> select months_between(sysdate,hiredate),SYSDATE,hiredate from emp;
MONTHS_BETWEEN(SYSDATE,HIREDATE) SYSDATE HIREDATE
-------------------------------- -------------- --------------
390.280195 25-6月 -13 17-12月-80
388.183421 25-6月 -13 20-2月 -81
388.118905 25-6月 -13 22-2月 -81
386.764066 25-6月 -13 02-4月 -81
380.925357 25-6月 -13 28-9月 -81
385.796324 25-6月 -13 01-5月 -81
384.53826 25-6月 -13 09-6月 -81
379.280195 25-6月 -13 17-11月-81
381.570518 25-6月 -13 08-9月 -81
378.731808 25-6月 -13 03-12月-81
378.731808 25-6月 -13 03-12月-81
377.086647 25-6月 -13 23-1月 -82
已选择12行。
显示6个月后是哪一天
SQL> select add_months(hiredate,6),hiredate from emp --6个月后;
ADD_MONTHS(HIR HIREDATE
-------------- --------------
17-6月 -81 17-12月-80
20-8月 -81 20-2月 -81
22-8月 -81 22-2月 -81
02-10月-81 02-4月 -81
28-3月 -82 28-9月 -81
01-11月-81 01-5月 -81
09-12月-81 09-6月 -81
17-5月 -82 17-11月-81
08-3月 -82 08-9月 -81
03-6月 -82 03-12月-81
03-6月 -82 03-12月-81
23-7月 -82 23-1月 -82
已选择12行。
此日期算起,下一个星期二是哪一天。
SQL> select next_day(hiredate,'星期二'),hiredate from emp --当前日期的下一个星期二;
NEXT_DAY(HIRED HIREDATE
-------------- --------------
23-12月-80 17-12月-80
24-2月 -81 20-2月 -81
24-2月 -81 22-2月 -81
07-4月 -81 02-4月 -81
29-9月 -81 28-9月 -81
05-5月 -81 01-5月 -81
16-6月 -81 09-6月 -81
24-11月-81 17-11月-81
15-9月 -81 08-9月 -81
08-12月-81 03-12月-81
08-12月-81 03-12月-81
26-1月 -82 23-1月 -82
已选择12行。
注:日期和当前客户端的字符集有关,如果是英文的客户端就用“Tuesday ” ,如果是中文的客户端就用“星期二”。日期是格式和字符集敏感的。
此日期所在月的最后一天
SQL> select last_day(hiredate),hiredate from emp --当前日期的月底;
LAST_DAY(HIRED HIREDATE
-------------- --------------
31-12月-80 17-12月-80
28-2月 -81 20-2月 -81
28-2月 -81 22-2月 -81
30-4月 -81 02-4月 -81
30-9月 -81 28-9月 -81
31-5月 -81 01-5月 -81
30-6月 -81 09-6月 -81
30-11月-81 17-11月-81
30-9月 -81 08-9月 -81
31-12月-81 03-12月-81
31-12月-81 03-12月-81
31-1月 -82 23-1月 -82
已选择12行。
日期的进位和截取
SQL> select hiredate,round(hiredate,'mm') ,round(hiredate,'month') from emp;
HIREDATE ROUND(HIREDATE ROUND(HIREDATE
-------------- -------------- --------------
17-12月-80 01-1月 -81 01-1月 -81
20-2月 -81 01-3月 -81 01-3月 -81
22-2月 -81 01-3月 -81 01-3月 -81
02-4月 -81 01-4月 -81 01-4月 -81
28-9月 -81 01-10月-81 01-10月-81
01-5月 -81 01-5月 -81 01-5月 -81
09-6月 -81 01-6月 -81 01-6月 -81
17-11月-81 01-12月-81 01-12月-81
08-9月 -81 01-9月 -81 01-9月 -81
03-12月-81 01-12月-81 01-12月-81
03-12月-81 01-12月-81 01-12月-81
23-1月 -82 01-2月 -82 01-2月 -82
已选择12行。
SQL> select hiredate,round(hiredate,'yyyy') ,round(hiredate,'year') from emp;
HIREDATE ROUND(HIREDATE ROUND(HIREDATE
-------------- -------------- --------------
17-12月-80 01-1月 -81 01-1月 -81
20-2月 -81 01-1月 -81 01-1月 -81
22-2月 -81 01-1月 -81 01-1月 -81
02-4月 -81 01-1月 -81 01-1月 -81
28-9月 -81 01-1月 -82 01-1月 -82
01-5月 -81 01-1月 -81 01-1月 -81
09-6月 -81 01-1月 -81 01-1月 -81
17-11月-81 01-1月 -82 01-1月 -82
08-9月 -81 01-1月 -82 01-1月 -82
03-12月-81 01-1月 -82 01-1月 -82
03-12月-81 01-1月 -82 01-1月 -82
23-1月 -82 01-1月 -82 01-1月 -82
已选择12行。
SQL> select hiredate,trunc(hiredate,'mm') ,trunc(hiredate,'month') from emp;
HIREDATE TRUNC(HIREDATE TRUNC(HIREDATE
-------------- -------------- --------------
17-12月-80 01-12月-80 01-12月-80
20-2月 -81 01-2月 -81 01-2月 -81
22-2月 -81 01-2月 -81 01-2月 -81
02-4月 -81 01-4月 -81 01-4月 -81
28-9月 -81 01-9月 -81 01-9月 -81
01-5月 -81 01-5月 -81 01-5月 -81
09-6月 -81 01-6月 -81 01-6月 -81
17-11月-81 01-11月-81 01-11月-81
08-9月 -81 01-9月 -81 01-9月 -81
03-12月-81 01-12月-81 01-12月-81
03-12月-81 01-12月-81 01-12月-81
23-1月 -82 01-1月 -82 01-1月 -82
已选择12行。
SQL> select hiredate,trunc(hiredate,'yyyy') ,trunc(hiredate,'year') from emp;
HIREDATE TRUNC(HIREDATE TRUNC(HIREDATE
-------------- -------------- --------------
17-12月-80 01-1月 -80 01-1月 -80
20-2月 -81 01-1月 -81 01-1月 -81
22-2月 -81 01-1月 -81 01-1月 -81
02-4月 -81 01-1月 -81 01-1月 -81
28-9月 -81 01-1月 -81 01-1月 -81
01-5月 -81 01-1月 -81 01-1月 -81
09-6月 -81 01-1月 -81 01-1月 -81
17-11月-81 01-1月 -81 01-1月 -81
08-9月 -81 01-1月 -81 01-1月 -81
03-12月-81 01-1月 -81 01-1月 -81
03-12月-81 01-1月 -81 01-1月 -81
23-1月 -82 01-1月 -82 01-1月 -82
已选择12行。
日期的截取与年,月,日,时,分,秒为中心。
extract函数
语法:EXTRACT ([YEAR] [MONTH][DAY] FROM[日期类型表达式])
SQL> select empno,ename,hiredate,extract(month from hiredate) month
from emp where deptno=10;
EMPNO ENAME HIREDATE MONTH
---------- ---------- -------------- ----------
7782 CLARK 09-6月 -81 6
7839 KING 17-11月-81 11
7934 MILLER 23-1月 -82 1
数据类型的隐式转换
字符串可以转化为数字和日期。
数字要合法,日期要格式匹配。
SQL> select ename,empno from emp where empno='7900';
ENAME EMPNO
---------- ----------
JAMES 7900
数字和日期在赋值的时候可以转换为字符串,但在表达式的时候不可以。
SQL> select ename,empno from emp where ename='123';
未选定行
SQL> select ename,empno from emp where ename=123;
select ename,empno from emp where ename=123
*
第 1 行出现错误:
ORA-01722: 无效数字
数据类型的显式转换
通常是在字符类型,日期类型,数字类型之间进行显性转换。
主要有3个显性函数:
–TO_CHAR
–TO_NUMBER
–TO_DATE
TO_CHAR(date|number[,‘fmt’]) 把日期类型/数字类型的表达式或列转换为变长类型字符类型。
- ‘fmt’指的是需要显示的格式
- 需要写在单引号中,并且是大小写敏感
- 可包含任何有效的日期格式
- fm表示去除生成结果的前导零或空格
日期转化为字符串
SQL> select ename,to_char(hiredate,'yyyy/mm/dd') from emp;
ENAME TO_CHAR(HI
---------- ----------
SMITH 1980/12/17
ALLEN 1981/02/20
WARD 1981/02/22
JONES 1981/04/02
MARTIN 1981/09/28
BLAKE 1981/05/01
CLARK 1981/06/09
KING 1981/11/17
TURNER 1981/09/08
JAMES 1981/12/03
FORD 1981/12/03
MILLER 1982/01/23
已选择12行。
fm去掉前面的0或空格
SQL> select ename,to_char(hiredate,'fmyyyy/mm/dd') from emp;
ENAME TO_CHAR(HI
---------- ----------
SMITH 1980/12/17
ALLEN 1981/2/20
WARD 1981/2/22
JONES 1981/4/2
MARTIN 1981/9/28
BLAKE 1981/5/1
CLARK 1981/6/9
KING 1981/11/17
TURNER 1981/9/8
JAMES 1981/12/3
FORD 1981/12/3
MILLER 1982/1/23
已选择12行。
格式内加入字符串用双引
SQL> select to_char(hiredate,'fmyyyy "年" mm "月"') from emp;
TO_CHAR(HIRED
-------------
1980 年 12 月
1981 年 2 月
1981 年 2 月
1981 年 4 月
1981 年 9 月
1981 年 5 月
1981 年 6 月
1981 年 11 月
1981 年 9 月
1981 年 12 月
1981 年 12 月
1982 年 1 月
已选择12行。
当前距离零点的秒数
SQL> select sysdate,to_char(sysdate,'sssss') ss from dual;
SYSDATE SS
-------------- -----
25-6月 -13 60442
常用日期格式:
-
- YYYY:4位数字表示年份;
- YY:2位数字表示年份,但是无世纪转换(与RR区别在后面章节介绍);
- RR:2位数字表示年份,有世纪转换(与YY区别在后面章节介绍);
- YEAR:年份的英文拼写;
- MM:两位数字表示月份;
- MONTH:月份英文拼写;
- DY:星期的英文前三位字母;
- DAY:星期的英文拼写;
- D:数字表示一星期的第几天,星期天是一周的第一天。
- DD:数字表示一个月中的第几天;
- DDD:数字表示一年中的第几天。
常用时间格式
-
- AM 或PM:上下午表示;
- HH 或HH12或HH24:数字表示小时。HH12代表12小时计时,HH24代表24小时计时;
- MI:数字表示分钟;
- SS:数字表示秒。
一些特殊格式
-
- TH:显示数字表示的英文序数词,如:DDTH显示天数的序数词。
- SP:显示数字表示的拼写。
- SPTH:显示数字表示的序数词的拼写。
数据类型的显式转换
数字转换为字符串
具体格式如下:
–9:一位数字;
–0:一位数字或前导零;
–$:显示为美元符号;
–L:显示按照区域设置的本地货币符号;
–.:小数点;
–,:千位分割符;
SQL> select ename,to_char(sal,'9999.000') salary from emp;
ENAME SALARY
---------- ---------
SMITH 801.000
ALLEN 1601.000
WARD 1250.000
JONES 2975.000
MARTIN 1250.000
BLAKE 2850.000
CLARK 2450.000
KING 5000.000
TURNER 1501.000
JAMES 950.000
FORD 3002.000
MILLER 1300.000
已选择12行。
SQL> select ename,to_char(sal,'$00099999000.00') salary from emp;
ENAME SALARY
---------- ----------------
SMITH $00000000801.00
ALLEN $00000001601.00
WARD $00000001250.00
JONES $00000002975.00
MARTIN $00000001250.00
BLAKE $00000002850.00
CLARK $00000002450.00
KING $00000005000.00
TURNER $00000001501.00
JAMES $00000000950.00
FORD $00000003002.00
MILLER $00000001300.00
已选择12行。
SQL> select ename,to_char(sal,'9G999D99') salary from emp;
ENAME SALARY
---------- ---------
SMITH 801.00
ALLEN 1,601.00
WARD 1,250.00
JONES 2,975.00
MARTIN 1,250.00
BLAKE 2,850.00
CLARK 2,450.00
KING 5,000.00
TURNER 1,501.00
JAMES 950.00
FORD 3,002.00
MILLER 1,300.00
已选择12行。
G是千分符,D是小数点。
在数据库中十六进制的表达是按照字符串来描述的,十进制的数转换为十六进制的数使用to_char函数。
SQL> select to_char(321,'xxxxx') from dual;
TO_CHAR(321,'xxxxx')
------------------------
141
其中xxxxx的位数要足够,不然会报错,多写几个足够大即可。
TO_NUMBER和TO_DATE函数
TO_NUMBER(char[,'fmt']) 把字符类型列或表达式转换为数字类型。
–使用格式和TO_CHAR中转换成字符类型中的格式相同。
–在转换时让Oracle知道字符串中每部分的功能。
TO_DATE(char[,'fmt']) 把字符类型列或表达式转换为日期类型。
–格式和TO_CHAR中转换成字符类型中的格式相同。
将十六进制的数转换为十进制用to_number
SQL> select to_number('abc32','xxxxxxxxxxxxxxx') from dual;
TO_NUMBER('ABC32','XXXXXXXXXXXXXXX')
------------------------------------
703538
to_date
SQL> select to_date('1月-15-13','month dd-yyyy') from dual;
TO_DATE('1月-
--------------
15-1月 -13
注:日期的语言和格式是敏感的!
SQL> select to_number('100.00','9G000D99') from dual;
TO_NUMBER('100.00','9G000D99')
------------------------------
100
rr和yy日期数据类型
yy是两位来表示年,世纪永远和说话者的当前世纪相同
RR比较灵活,分上半世纪和下半世纪。
- 当前年份0-49,指定日期是0-49时,返回当前世纪。
- 当前年份0-49,指定日期是50-99时,返回上个世纪。
- 当前年份50-99,指定日期是0-49时,返回下个世纪。
- 当前年份50-99,指定日期是50-99时,返回当前世纪。
SQL> select to_char(sysdate,'yyyy') "当前",
to_char(to_date('98','yy'),'yyyy') "yy98",
to_char(to_date('08','yy'),'yyyy') "yy08",
to_char(to_date('98','rr'),'yyyy') "rr98",
to_char(to_date('08','rr'),'yyyy') "rr08"
from dual;
当前 yy98 yy08 rr98 rr08
---- ---- ---- ---- ----
2013 2098 2008 1998 2008