在项目中遇到 曾有过Timestamp字段,遂百度找到一遍。方便以后查阅
Oracle针对不同的数据需求,提供了多种类、多层次的数据类型体系。我们在实际应用中,最好可以依据业务数据的实际形态和前端应用的语言、框架特性来确定字段类型的选择。
Date类型是我们经常使用的时间类型数据表示,包括了年月日时分秒信息。作为Date类型的一个拓展,Oracle提供了Timestamp数据类型,作为高精度时间类型的体现。
1、Timestamp的高精度
Timestamp在官方中的定义方式是timestamp(n),其中n表示秒级片段(fractional_seconds)的精确度。作为Date类型的一个拓展,Timestamp提供了更为精确的时间定位。
select systimestamp from dual;
SYSTIMESTAMP :
13-7月 -11 07.52.16.562000 下午 +08:00
select sysdate from dual;
SYSDATE
2011-7-13 20:13:55
使用 systimestamp 函数,我们可以获取到当前时间的timestamp with local time zone取值。默认情况下,我们发现和sysdate显示的有一些差异。控制和显示timestamp格式的参数,可以通过 v$nls_parameters 进行查看。
select * from v$nls_parameters;
PARAMETER VALUE
------------------------------ ----------------------------------------
(篇幅原因,有省略…)
NLS_SORT BINARY
NLS_TIME_FORMAT HH.MI.SSXFF AM
NLS_TIMESTAMP_FORMAT DD-MON-RR HH.MI.SSXFF AM
NLS_TIME_TZ_FORMAT HH.MI.SSXFF AM TZR
NLS_TIMESTAMP_TZ_FORMAT DD-MON-RR HH.MI.SSXFF AM TZR
19 rows selected
参数 nls_timestamp_format 和 nls_timestamp_tz_format 分别来控制 timestamp 和 timestamp with local zone 的显示格式。
上面systimestamp显示的信息,可以解析为:2011-7-13 19:52:16。稍稍费解的是秒后面的562000数字。这个是Timestamp的秒片段(fractional seconds),就是秒向下的精度划分。timestamp定义中的n就是指定的每秒划分的精度范围。
实际应用中,n取值为0-9,默认为6。从上面例子上的systimestamp函数返回值上看,也是的确如此。
create table t (d1 timestamp, d2 timestamp(0), d3 timestamp(9));
Table created
desc t;
Name Type Nullable Default Comments
---- ------------ -------- ------- --------
D1 TIMESTAMP(6) Y
D2 TIMESTAMP(0) Y
D3 TIMESTAMP(9) Y
那么,timestamp类型的高精度有什么作用呢?个人认为大部分还是为了前端并发访问时候的锁机制,还有一些特殊行业的高精度需求。很多开发框架都需要使用一个高精度的数据列来标记行访问的时间顺序,通过timestamp的精度,基本可以满足这部分的需要。
2、Timestamp with time zone
Timestamp类型的另一个特性就是时区timezone特性。我们知道世界各地所处的时区不同,对应同一个时刻显示的时间是不同的。所以如果精确定义一个时间点,特别是对应一个全球性系统的时候,时区Timezone是不可或缺的考虑因素。
Date类型只能适应于一般时间的表示,如果加入了时区因素,就无能为力了。在这样的情况下,就可以选择Timestamp类型的一个拓展类型,timestamp with time zone。这样就可以把当前对应的时区信息加入到数据列中。
函数systimestamp返回标准类型就是timestamp with time zone。与一般timestamp类型不同的是,timestamp with time zone额外加入了当前时区的信息。
select systimestamp from dual;
SYSTIMESTAMP
--------------------------------------------------------------------------------
13-7月 -11 07.52.16.562000 下午 +08:00
+08:00表示时区,全球有12个时区。系统的时区通过参数设置或者当前操作系统OS的配置来获取。
create table t (d1 date, d2 timestamp, d3 timestamp with time zone);
insert into t values (systimestamp, systimestamp, systimestamp);
Table created
1 row inserted
commit;
Commit complete
select * from t;
-------------------- -----------
加入时区信息之后,可以做到全球时间下的绝对时间比较。
此外,timestamp还有一个timestamp with local time zone的拓展类型。也包括时区信息,与time zone的差别有下面几个:
- 不管是什么时区的日期插入到数据库中,都会进行正规化工作。将其他时区的日期转化为数据库对应的时区(Database Time Zone)中;
- 当进行检索操作的时候,local time zone 类型数据又会被转化为当前检索会话对应的time zone中。这一系列的转化操作对end user而言都是透明的;
在对应会话和数据库的时区上,与系统参数NLS_TERRITORY是相关的。Oracle往往通过这个参数的国家设置来判断时区。而客户端的参数往往与nls_lang相关。
3、Timestamp显示格式控制
最后我们一起来看看 timestamp 显示的格式方式。默认情况下,timestamp 以及 timestamp with time zone 的显示是与系统参数 NLS_TIMESTAMP_FORMAT 和 NLS_TIMESTAMP_TZ_FORMAT 有关。在我们的实验环境下,两个格式字符串(format string)分别为:
NLS_TIMESTAMP_FORMAT DD-MON-RR HH.MI.SSXFF AM
NLS_TIMESTAMP_TZ_FORMAT DD-MON-RR HH.MI.SSXFF AM TZR
其中,DD、MON、HH和MI都是我们非常熟悉的日期格式字符串。RR表示使用年的后两位进行表示。而SSXFF是一个组合条件,应该被拆分为SS、X和FF三个部分。SS表示秒信息,X表示基数开关,而FF表示小于一秒的时间片段。
X表示的基数开关是什么意思呢?我们通过实验就可以看出情况。
select to_char(systimestamp,'DD-MON-RR HH.MI.SSXFF AM') SSXFF, to_char(systimestamp,'DD-MON-RR HH.MI.SSFF AM') SSFF from dual;
加入了X表示开关之后,就在秒为加入了一个 . 号表示分割。便于查看。
而AM表示是否使用(AM和PM)显示上下午信息, TZR 则表示是否显示出时区信息。
当显示timestamp类型的时候,如果没有明确指定显示格式,系统会自动使用 NLS_TIMESTAMP_FORMAT 系列参数。
select to_char(systimestamp, 'yyyy-mm-dd hh24:mi:ss ff tzr') from dual;
--------------------------------------------------------------
2011-07-13 21:40:50 265000 +08:00
如果期望在会话(或者系统)一级修改参数,就要使用 alter session 或者alter system方法。
select to_char(systimestamp) from dual;
TO_CHAR(SYSTIMESTAMP)
-----------------------------------------------------------------------
13-7月 -11 09.42.44.343000 下午 +08:00
//对当前会话修改参数;
alter session set nls_timestamp_tz_format='yyyy-mm-dd hh24:mi:ss ff tzr';
Session altered
select to_char(systimestamp) from dual;
TO_CHAR(SYSTIMESTAMP)
--------------------------------------------------------------
2011-07-13 21:43:18 984000 +08:00
4、结论
timestamp 系列类型是对 Oracle Date 类型的一种有益补充。在需要的场合下,可以适当使用。
转载自: http://blog.itpub.net/17203031/viewspace-702132