oracle数据类型分析

来源:互联网 发布:linux五笔输入法下载 编辑:程序博客网 时间:2024/04/26 23:16

数据类型 参数 描述 char(n) n=1 to 2000字节 定长字符串,n字节长,如果不指定长度,缺省为1个字节长(一个汉字为2字节) varchar2(n) n=1 to 4000字节 可变长的字符串,具体定义时指明最大长度n,
这种数据类型可以放数字、字母以及ASCII码字符集(或者EBCDIC等数据库系统接受的字符集标准)中的所有符号。
如果数据长度没有达到最大值n,Oracle 8i会根据数据大小自动调节字段长度,
如果你的数据前后有空格,Oracle 8i会自动将其删去。VARCHAR2是最常用的数据类型。
可做索引的最大长度3209。 number(m,n) m=1 to 38
n=-84 to 127 可变长的数值列,允许0、正值及负值,m是所有有效数字的位数,n是小数点以后的位数。
如:number(5,2),则这个字段的最大值是99,999,如果数值超出了位数限制就会被截取多余的位数。
如:number(5,2),但在一行数据中的这个字段输入575.316,则真正保存到字段中的数值是575.32。
如:number(3,0),输入575.316,真正保存的数据是575。 date 无 从公元前4712年1月1日到公元4712年12月31日的所有合法日期,
Oracle 8i其实在内部是按7个字节来保存日期数据,在定义中还包括小时、分、秒。
缺省格式为DD-MON-YY,如07-11月-00 表示2000年11月7日。 long 无 可变长字符列,最大长度限制是2GB,用于不需要作字符串搜索的长串数据,如果要进行字符搜索就要用varchar2类型。
long是一种较老的数据类型,将来会逐渐被BLOB、CLOB、NCLOB等大的对象数据类型所取代。 raw(n) n=1 to 2000 可变长二进制数据,在具体定义字段的时候必须指明最大长度n,Oracle 8i用这种格式来保存较小的图形文件或带格式的文本文件,如Miceosoft Word文档。
raw是一种较老的数据类型,将来会逐渐被BLOB、CLOB、NCLOB等大的对象数据类型所取代。 long raw 无 可变长二进制数据,最大长度是2GB。Oracle 8i用这种格式来保存较大的图形文件或带格式的文本文件,如Miceosoft Word文档,以及音频、视频等非文本文件。
在同一张表中不能同时有long类型和long raw类型,long raw也是一种较老的数据类型,将来会逐渐被BLOB、CLOB、NCLOB等大的对象数据类型所取代。 blob
clob
nclob 无 三种大型对象(LOB),用来保存较大的图形文件或带格式的文本文件,如Miceosoft Word文档,以及音频、视频等非文本文件,最大长度是4GB。
LOB有几种类型,取决于你使用的字节的类型,Oracle 8i实实在在地将这些数据存储在数据库内部保存。
可以执行读取、存储、写入等特殊操作。 bfile 无 在数据库外部保存的大型二进制对象文件,最大长度是4GB。
这种外部的LOB类型,通过数据库记录变化情况,但是数据的具体保存是在数据库外部进行的。
Oracle 8i可以读取、查询BFILE,但是不能写入。
大小由操作系统决定。

 ORACLE中的数据类型分类:

1、字符数据类型:包括我CHAR,VARCHAR2,LONG。
CHAR型可以存储字母数字值,这种数据类型的
列长度可以是1到2000个字节。如果未指明,则默认其占用一个字节,如果用户输入的值小于指定的长度,数据库则用空格填充至固定长度。
VARCHAR2型其实就是VARCHAR,只不过后面多了一个数字2,VARCHAR2就是VARCHAR的同义词,也称别名。数据类型大小在1至4000个字节,但是和CHAR不同的一点是:当你定义了VARCHAR2长度为30,但是你只输入了10个字符,这时VARCHAR2不会像CHAR一样填充,在数据库中只有10具字节。
LONG型:此数据类型用来存储可变长度的字符数据,最多能存储2GB。但是有一些限制:一个表中只有一列可以为LONG型,LONG列不能定义为主键或唯一约束,不能建立索引,过程或存储过程不能接受LONG数据类型的参数。
2、数值数据类型只有NUMBER型,但是NUMBER功能不小,它可以存储正数,负数,零,定点数和精度为30位的浮点数。格式为(P=38,S=0),其中P为精度,表示数字的总位数,它在1-38之间,S为范围,表示小数点右边的数字的位数,它在-84至127之间。
3、日期时间数据类型:有DATE数据类型,TIMESTAMP数据类型。
DATE用于存储表中的日期和时间数据,ORACLE使用自己的格式存储日期,使用7个字节固定长度,每个字节分别存储世纪,年月日,小时,分和秒。日期数据类型的值从公元前4712年1月1日到公元9999年12月31日。ORACLE中的SYSDATE函数用于返回当前的日期和时间。
TIMESTAMP数据类型与DATE不同的是:它还返回当前的时区。
4RAW和LONG RAW 数据类型
此种数据类型主要用于存储二进制数据。
RAW用于存储基于字节的数据,最多能存储2000个字节,它没有默认大小,所以在使用时要指定大小,可以建立索引。
RAW LONG用于存储可变长度的二进制数据,最多能存储2GB,它受的限制和LONG类型一样。
5、LOB数据类型
LOB又称为“大对象”数据类型:主要有CLOB,BLOB,BFILE,三种子类型。
CLOB代表(CHARACTER LOB),它能够存储大量字符数据,可以存储非结构化的XML文档。
BLOG代表(BINARY LOB),它可以存储较大的二进制对象;如图形,音视频剪辑。
BFILE代表(BINARY FILE),它能够将二进制文件存储在数据库外部的操作系统文件中,注意是二进制文件,不是一般数据,BFILE列存储一个BFILE定位器,它指向位于服务器文件系统上的二进制文件,支持的文件最大为4GB。不过ORACLE10以上的会更大,这还需要硬件方面的支持。


ORACLE NUMBER数据类型:

一、oracle的number类型精度、刻度范围

number(p,s)

p:1---38
s:-84---127

有效数位:从左边第一个不为0的数算起,小数点和负号不计入有效位数。

p>0,对s分2种情况:

1. s>0

精确到小数点右边s位,并四舍五入。然后检验有效数位是否<=p;

ZWF.YUDONG>create table t_n(id number(5,2));

Table created.

ZWF.YUDONG>insert into t_n values(123.45);

1 row created.

ZWF.YUDONG>insert into t_n values(123.455);

1 row created.

ZWF.YUDONG>select * from t_n;

       ID
----------
123.45
123.46

2 rows selected.

ZWF.YUDONG>insert into t_n values(1.234);

1 row created.

ZWF.YUDONG>select * from t_n;

       ID
----------
123.45
123.46
   1.23

3 rows selected.

ZWF.YUDONG>insert into t_n values(.001);

1 row created.

ZWF.YUDONG>select * from t_n;

       ID
----------
123.45
123.46
   1.23
      0

4 rows selected.

ZWF.YUDONG>insert into t_n values(1234.56);
insert into t_n values(1234.56)
                      *
ERROR at line 1:
ORA-01438: value larger than specified precision allowed for this column


如果s>p,小数点右边至少有s-p个0填充。

ZWF.YUDONG>create table t_n(id number(4,5));

Table created.

ZWF.YUDONG>insert into t_n values(1);
insert into t_n values(1)
                      *
ERROR at line 1:
ORA-01438: value larger than specified precision allowed for this column


ZWF.YUDONG>insert into t_n values(.1);
insert into t_n values(.1)
                      *
ERROR at line 1:
ORA-01438: value larger than specified precision allowed for this column


ZWF.YUDONG>insert into t_n values(.01);

1 row created.

ZWF.YUDONG>commit;

Commit complete.

ZWF.YUDONG>select * from t_n;

       ID
----------
   .01

1 row selected.

ZWF.YUDONG>insert into t_n values(.001);

1 row created.

ZWF.YUDONG>insert into t_n values(.0001);

1 row created.

ZWF.YUDONG>insert into t_n values(.00001);

1 row created.

ZWF.YUDONG>insert into t_n values(.000001); --超过刻度存储0

1 row created.

ZWF.YUDONG>select * from t_n;

       ID
----------
   .01
   .001
    .0001
.00001
      0


10 rows selected.

ZWF.YUDONG>col dp for a50
ZWF.YUDONG>select id,dump(id) dp,length(id),vsize(id) from t_n;   --vsize和dump的是字节数,length是数值实际位数(含小数点)

       ID DP                                              LENGTH(ID)   VSIZE(ID)
---------- -------------------------------------------------- ---------- ----------
   .01 Typ=2 Len=2: 192,2                                        3       2
   .001 Typ=2 Len=2: 191,11                                         4       2
    .0001 Typ=2 Len=2: 191,2                                        5       2
.00001 Typ=2 Len=2: 190,11                                         6       2
      0 Typ=2 Len=1: 128                                            1       1

5 rows selected.


2. s<0

精确到小数点左边s位,并四舍五入。然后检验有效数位是否<=p+|s|

ZWF.YUDONG>create table t_n(id number(5,-2));

Table created.

ZWF.YUDONG>insert into t_n values(12345);

1 row created.

ZWF.YUDONG>select * from t_n;

       ID
----------
    12300

1 row selected.

ZWF.YUDONG>insert into t_n values(123456);

1 row created.

ZWF.YUDONG>insert into t_n values(1234567);

1 row created.

ZWF.YUDONG>select * from t_n;

       ID
----------
    12300
123500
1234600

3 rows selected.

ZWF.YUDONG>insert into t_n values(12345678);
insert into t_n values(12345678)
                      *
ERROR at line 1:
ORA-01438: value larger than specified precision allowed for this column


二、oracle的number类型存储结构:

oracle采用变长存储number数据类型(按一定规则进行转换成2进制编码格式存储)。

oracle数据库中存储的number类型包含3个部分: HEAD部分, DATA部分, 符号位。

对正数来说, 符号位省略, 对0来说, oracle存储的是X80(128)。

ZWF.YUDONG>select dump(0) from dual;

DUMP(0)
----------------
Typ=2 Len=1: 128

1 row selected.

ZWF.YUDONG>select dump(1) from dual;

DUMP(1)
------------------
Typ=2 Len=2: 193,2

1 row selected.

ZWF.YUDONG>select dump(-1) from dual;

DUMP(-1)
-----------------------
Typ=2 Len=3: 62,100,102

1 row selected.

HEAD部分为一个字节8位, 就是前面看到的128, 193,62。由该部分我们可以看出number类型的基本信息,因为设计这种存储格式的时候, oracle希望以十六进制00-FF来表示所有
的number, 所以为了编码的对称, 首先将number分为正负, 所以以00-FF的中间位置80, 也就是十进制的128来表示0, HEAD部分小于80,即为负数,大于80即为正数。ORACLE再次对
00-80, 80-FF进行对分:

00-3E 表示: number <= -1
3F-7F 表示: -1 < number < 0
81-C0 表示: 0 < number < 1
C1-FF 表示:number >= 1

从HEAD部分我们可以也看出数据的位数信息,是否含有小数,可以根据HEAD的信息判断小数点的位置。由于数据部分低位2的n次方位个0是不被存储的,数据展现的时候oracle
根据HEAD的信息给补充末位的0。

ZWF.YUDONG>select dump(123456789) from dual;

DUMP(123456789)
------------------------------
Typ=2 Len=6: 197,2,24,46,68,90 --197(C5)的含义:表示数字123456789大于1,197-193(数字1占用2个字节该值为193) = 4 ,所以该数字占用6(2+4)个字节。

1 row selected.


然后,我们再来看数据部分, ORACLE对十进制的数字(整数部分,小数部分正好相反)是两位两位进行存储的(从右往左的顺序), 例如对1234, ORACLE会分别对12, 34进行存储.
所以只需要对(+-)1-99进行编码

1 --- 99 分别用十六进制2-64表示,就是2-100,

-1--- -99 用十六进制64-2表示,就是100-2

ZWF.YUDONG>select dump(12345) from dual;

DUMP(12345)
------------------------
Typ=2 Len=4: 195,2,24,46   --数据部分2,24,46 表示 (2-1=1,24-1=23,46-1=45);HEAD部分表示12345 >= 1,占用195-193+2=4字节。

1 row selected.


SYS.YUDONG>select dump(1100) from dual;  

DUMP(1100)
-------------------
Typ=2 Len=2: 194,12    --如果从右边起,连续2的n次方位为0,oracle一次排触(不存储)只是位数加1。可以对比dump(11)的情况看看。

1 row selected.

SYS.YUDONG>select dump(11) from dual;

DUMP(11)
-------------------
Typ=2 Len=2: 193,12        --这里数据部分和1100是一样的,末位的2个0没有实际存储,长度193比194小1。

1 row selected.

--对于含小数(负数、整数2种情况)的情况:

1、负数

SYS.YUDONG>select dump(-1.2) from dual;

DUMP(-1.2)
--------------------------
Typ=2 Len=4: 62,100,81,102 --HEAD=62(3E)表示该数值小于等于-1;数据部分:整数部分的-1存储为100,小数部分从左往右2位一结合,不足2位后边补一个1。
                           对应关系变为9,8...1表示1,2...9,看下面几个例子,如果足2位,还是按照上边说的规律(-1--- -99 用十六进制64-2表示,就是100-2)。

1 row selected.


ZWF.YUDONG>select dump(-2.1) from dual;

DUMP(-2.1)
-------------------------
Typ=2 Len=4: 62,99,91,102

1 row selected.

ZWF.YUDONG>select dump(-2.2) from dual;

DUMP(-2.2)
-------------------------
Typ=2 Len=4: 62,99,81,102

1 row selected.

ZWF.YUDONG>select dump(-2.9) from dual;

DUMP(-2.9)
-------------------------
Typ=2 Len=4: 62,99,11,102

1 row selected.

ZWF.YUDONG>select dump(-2.12) from dual;

DUMP(-2.12)
-------------------------
Typ=2 Len=4: 62,99,89,102

1 row selected.

ZWF.YUDONG>select dump(-2.13) from dual;

DUMP(-2.13)
-------------------------
Typ=2 Len=4: 62,99,88,102

1 row selected.

ZWF.YUDONG>select dump(-2.123) from dual;

DUMP(-2.123)
----------------------------
Typ=2 Len=5: 62,99,89,71,102

1 row selected.


2、正数

SYS.YUDONG>select dump(1.222) from dual;

DUMP(1.222)
------------------------
Typ=2 Len=4: 193,2,23,21    --HEAD=193(C1)表示该数字大于等于1;数据部分:整数部分存储2(2-1=1),小数部分从左往右2位一结合,23(23-1=22)表示22,后边还剩下一个2,
不足2位的末尾补充一个1,也就是等于1.2220

1 row selected.

ZWF.YUDONG>select dump(1.2220) from dual;

DUMP(1.2220)
------------------------
Typ=2 Len=4: 193,2,23,21

1 row selected.


符号位: 用的是(+-)1-99都不可能用到的编码66(102)来表示,有资料说为了处理排序问题(未加考证)。根据HEAD部分可以做初步判断,根据我们说的HEAD部分的四个范围,
如果2个数值不在一个范围,立即可以看出大小,如果在一个范围其实也可以根据其正负+绝对值来进行排序了,正数绝对值大的就大,负数则相反,为何还要用到这个符号位?

oracle中一些特殊数据类型的用法:

一 . raw

RAW,类似于CHAR,声明方式RAW(L),L为长度,以字节为单位,作为数据库列最大2000,作为变量最大32767字节。

LONG RAW,类似于LONG,作为数据库列最大存储2G字节的数据,作为变量最大32760字节

建表操作:

create table raw_test (id number, raw_date raw(10));

插入raw数据操作:

insert into raw_test values (1, hextoraw('ff'));

insert into raw_test values (utl_raw.cast_to_raw('051'));//这个函数我在sqlplus里面试验不行

删除表操作:

drop table raw_test;

当使用HEXTORAW时,会把字符串中数据当作16进制数。而使用UTL_RAW.CAST_TO_RAW时,直接把字符串中每个字符的ASCII码存放到RAW类型的字段中

二   date,datetime,timestamp

date插入的时候使用to_char函数,如下

SQL> desc test45;
名称                                       是否为空? 类型
----------------------------------------- -------- ----------------------------
A1                                                  FLOAT(126)
A2                                                  DATE

SQL> insert into test45 values(12.445,to_date('2006-11-30','yyyy-mm-dd'));

 

timestamp:

Oracle定义语法:
TIMESTAMP [(fractional_seconds_precision)]

fractional_seconds_precision 的范围为0到9, 默认为6. 与DATE类型相比该类型可以保存到微秒. 而且微秒的精确范围可以保存到0到9为数据. 在数据库中保存占7到11字节, 具体看你定义的fractional seconds的精度. 下面例子说明:

-- 建表包含timestamp类型.
SQL> create table tm(a timestamp);

Table created.

-- 注意这地方的FF中的'123456789', 这就是我刚说的微秒的精确范围, 上面定义的时候没有指定, 这就是使用默认的6了, 在下面"desc tm"处就可以看到的.
SQL> insert into tm values(TO_TIMESTAMP('2006-12-01 12:12:09.123456789', 'YYYY-MM-DD HH24:MI:SS.FF'));

1 row created.

-- 从这地方就可以看出来默认是6了. 要是你想使用更高的精确度就可以自己人为的指定了. create table tm(a timestamp(9)); 这样就可以的.
SQL> desc tm;
Name      Null?     Type
------- -------- ----------------------------
A                  TIMESTAMP(6)

--从这就可以看出来吧, 精确度为6时候,在插入数据时就使用了四舍五入了.
SQL> select * from tm;

A
---------------------------------------------------------------------------
01-DEC-06 12.12.09.123457 PM

-- 如果我想插入的数据超过了最大的9位时就会出错了的.
SQL> insert into tm values(TO_TIMESTAMP('2006-12-01 12:23:09.1234567890', 'YYYY-MM-DD HH24:MI:SS.FF'));
insert into tm values(TO_TIMESTAMP('2006-12-01 12:23:09.1234567890', 'YYYY-MM-DD HH24:MI:SS.FF'))
                                    *
ERROR at line 1:
ORA-01830: date format picture ends before converting entire input string

-----------------------
查看当前的timestamp时间是CURRENT_TIMESTAMP
select current_timestamp from dual;

SQL> desc test47;
名称                                       是否为空? 类型
----------------------------------------- -------- -------------------------
A1                                                  RAW(10)
A2                                                  TIMESTAMP(6)

SQL>   insert into test47 values(hextoraw('ff'),systimestamp);

 

 

三   interval

INTERVAL 'integer [- integer]' {YEAR | MONTH} [(precision)][TO {YEAR | MONTH}]

该数据类型常用来表示一段时间差, 注意时间差只精确到年和月. precision为年或月的精确域, 有效范围是0到9, 默认值为2.

eg:
INTERVAL '123-2' YEAR(3) TO MONTH    
表示: 123年2个月, "YEAR(3)" 表示年的精度为3, 可见"123"刚好为3为有效数值, 如果该处YEAR(n), n<3就会出错, 注意默认是2.

INTERVAL '123' YEAR(3)
表示: 123年0个月

INTERVAL '300' MONTH(3)
表示: 300个月, 注意该处MONTH的精度是3啊.

INTERVAL '4' YEAR    
表示: 4年, 同 INTERVAL '4-0' YEAR TO MONTH 是一样的

INTERVAL '50' MONTH    
表示: 50个月, 同 INTERVAL '4-2' YEAR TO MONTH 是一样

INTERVAL '123' YEAR    
表示: 该处表示有错误, 123精度是3了, 但系统默认是2, 所以该处应该写成 INTERVAL '123' YEAR(3) 或"3"改成大于3小于等于9的数值都可以的

INTERVAL '5-3' YEAR TO MONTH + INTERVAL '20' MONTH =
INTERVAL '6-11' YEAR TO MONTH
表示: 5年3个月 + 20个月 = 6年11个月

与该类型相关的函数:
NUMTODSINTERVAL(n, 'interval_unit')
将n转换成interval_unit所指定的值, interval_unit可以为: DAY, HOUR, MINUTE, SECOND
注意该函数不可以转换成YEAR和MONTH的.

NUMTOYMINTERVAL(n, 'interval_unit')
interval_unit可以为: YEAR, MONTH

eg: (Oracle Version 9204, RedHat Linux 9.0)
SQL> select numtodsinterval(100,'DAY') from dual;

NUMTODSINTERVAL(100,'DAY')                                                     
---------------------------------------------------------------------------    
+000000100 00:00:00.000000000                                                  

SQL> c/DAY/SECOND
   1* select numtodsinterval(100,'SECOND') from dual
SQL> /

NUMTODSINTERVAL(100,'SECOND')                                                  
---------------------------------------------------------------------------    
+000000000 00:01:40.000000000                                                  

SQL> c/SECOND/MINUTE
   1* select numtodsinterval(100,'MINUTE') from dual
SQL> /

NUMTODSINTERVAL(100,'MINUTE')                                                  
---------------------------------------------------------------------------    
+000000000 01:40:00.000000000                                                  

SQL> c/MINUTE/HOUR
   1* select numtodsinterval(100,'HOUR') from dual
SQL> /

NUMTODSINTERVAL(100,'HOUR')                                                    
---------------------------------------------------------------------------    
+000000004 04:00:00.000000000                                                  

SQL> c/HOUR/YEAR
   1* select numtodsinterval(100,'YEAR') from dual
SQL> /
select numtodsinterval(100,'YEAR') from dual
                            *
ERROR at line 1:
ORA-01760: illegal argument for function

SQL> select numtoyminterval(100,'year') from dual;

NUMTOYMINTERVAL(100,'YEAR')                                                    
---------------------------------------------------------------------------    
+000000100-00                                                                  

SQL> c/year/month
   1* select numtoyminterval(100,'month') from dual
SQL> /

NUMTOYMINTERVAL(100,'MONTH')                                                   
---------------------------------------------------------------------------    
+000000008-04                                                                  


时间的计算:
SQL> select to_date('1999-12-12','yyyy-mm-dd') - to_date('1999-12-01','yyyy-mm-dd') from dual;

TO_DATE('1999-12-12','YYYY-MM-DD')-TO_DATE('1999-12-01','YYYY-MM-DD')          
---------------------------------------------------------------------          
                                                                    11          
-- 可以相减的结果为天.

ORACLE DATE和TIMESTAMP数据类型的比较:

DATE数据类型
  
  这个数据类型我们实在是太熟悉了,当我们需要表示日期和时间的话都会想到date类型。它可以存储月,年,日,世纪,时,分和秒。它典型地用来表示什么时候事情已经发生或将要发生。DATE数据类型的问题在于它表示两个事件发生时间间隔的度量粒度是秒。这个问题将在文章稍后讨论timestamp的时候被解决。可以使用TO_CHAR函数把DATE数据进行传统地包装,达到表示成多种格式的目的。
  
  SQL> SELECT TO_CHAR(date1,'MM/DD/YYYY HH24:MI:SS') "Date" FROM date_table;
  
  Date
  
  ---------------------------
  
  06/20/2003 16:55:14
  
  06/26/2003 11:16:36
  
  我见到的大多数人陷入的麻烦就是计算两个时间间的间隔年数、月数、天数、小时数和秒数。你需要明白的是,当你进行两个日期的相减运算的时候,得到的是天数。你需要乘上每天的秒数(1天=86400秒),然后,你可以再次计算得到你想要的间隔数。下面就是我的解决方法,可以精确计算出两个时间的间隔。我明白这个例子可以更简短些,但是我是为了显示所有的数字来强调计算方式。
  
  1     SELECT TO_CHAR(date1,'MMDDYYYY:HH24:MI:SS') date1,
  
   2     TO_CHAR(date2,'MMDDYYYY:HH24:MI:SS') date2,
  
   3     trunc(86400*(date2-date1))-
  
   4     60*(trunc((86400*(date2-date1))/60)) seconds,
  
   5     trunc((86400*(date2-date1))/60)-
  
   6     60*(trunc(((86400*(date2-date1))/60)/60)) minutes,
  
   7     trunc(((86400*(date2-date1))/60)/60)-
  
   8     24*(trunc((((86400*(date2-date1))/60)/60)/24)) hours,
  
   9     trunc((((86400*(date2-date1))/60)/60)/24) days,
  
  10     trunc(((((86400*(date2-date1))/60)/60)/24)/7) weeks
  
  11*    FROM date_table
  
  DATE1       DATE2        SECONDS  MINUTES   HOURS   DAYS   WEEKS
  
  ----------------- ----------------- ---------- ---------- ---------- ---------- ----------
  
  06202003:16:55:14 07082003:11:22:57     43     27     18    17     2
  
  06262003:11:16:36 07082003:11:22:57     21     6     0    12     1
  
  TIMESTAMP 数据类型
  
  DATE数据类型的主要问题是它粒度不能足够区别出两个事件哪个先发生。ORACLE已经在DATE数据类型上扩展出来了TIMESTAMP数据类型,它包括了所有DATE数据类型的年月日时分秒的信息,而且包括了小数秒的信息。如果你想把DATE类型转换成TIMESTAMP类型,就使用CAST函数。
  
  SQL> SELECT CAST(date1 AS TIMESTAMP) "Date" FROM t;
  
  Date
  
  -----------------------------------------------------
  
  20-JUN-03 04.55.14.000000 PM
  
  26-JUN-03 11.16.36.000000 AM
  
  正如你看到的,在转换后的时间段尾部有了一段“.000000”。这是因为从date转换过来的时候,没有小数秒的信息,缺省为0。而且显示格式是按照参数NLS_TIMESTAMP_FORMAT定的缺省格式显示。当你把一个表中date类型字段的数据移到另一个表的timestamp类型字段中去的时候,可以直接写INSERT SELECT语句,oracle会自动为你做转换的。
  
  1 SELECT TO_CHAR(time1,'MM/DD/YYYY HH24:MI:SS') "Date" FROM date_table
  
  Date
  
  -------------------
  
  06/20/2003 16:55:14
  
  06/26/2003 11:16:36

 

 

TIMESTAMP数据的格式化显示和DATE 数据一样。注意,to_char函数支持date和timestamp,但是trunc却不支持TIMESTAMP数据类型。这已经清楚表明了在当两个时间的差别极度重要的情况下,使用TIMESTAMP数据类型要比DATE数据类型更确切。
  
  如果你想显示TIMESTAMP的小数秒信息,参考下面:
  
  1 SELECT TO_CHAR(time1,'MM/DD/YYYY HH24:MI:SS:FF3') "Date" FROM date_table
  
  Date
  
  -----------------------
  
  06/20/2003 16:55:14:000
  
  06/26/2003 11:16:36:000
  
  在上例中,我只现实了小数点后3位的内容。
  
  计算timestamp间的数据差别要比老的date数据类型更容易。当你直接相减的话,看看会发生什么。结果将更容易理解,第一行的17天,18小时,27分钟和43秒。
  
  1 SELECT time1,
  
   2     time2,
  
   3     substr((time2-time1),instr((time2-time1),' ')+7,2)         seconds,
  
   4     substr((time2-time1),instr((time2-time1),' ')+4,2)         minutes,
  
   5     substr((time2-time1),instr((time2-time1),' ')+1,2)         hours,
  
   6     trunc(to_number(substr((time2-time1),1,instr(time2-time1,' '))))  days,
  
   7     trunc(to_number(substr((time2-time1),1,instr(time2-time1,' ')))/7) weeks
  
   8*  FROM date_table
  
  TIME1            TIME2           SECONDS MINUTES HOURS DAYS WEEKS
  
  -------------------------  -------------------------- ------- ------- ----- ---- -----
  
  06/20/2003:16:55:14:000000 07/08/2003:11:22:57:000000 43   27   18  17  2
  
  06/26/2003:11:16:36:000000 07/08/2003:11:22:57:000000 21   06   00  12  1
  
  这就意味着不再需要关心一天有多少秒在麻烦的计算中。因此,得到天数、月数、天数、时数、分钟数和秒数就成为用substr函数摘取出数字的事情了。
  
  系统日期和时间
  
  为了得到系统时间,返回成date数据类型。你可以使用sysdate函数。
  
  SQL> SELECT SYSDATE FROM DUAL;
  
  为了得到系统时间,返回成timestamp数据类型。你可以使用systimpstamp函数。
  
  SQL> SELECT SYSTIMESTAMP FROM DUAL;
  
  你可以设置初始化参数FIXED_DATE指定sysdate函数返回一个固定值。这用在测试日期和时间敏感的代码。注意,这个参数对于systimestamp函数无效。
  
  SQL> ALTER SYSTEM SET fixed_date = '2003-01-01-10:00:00';
  
  System altered.
  
  SQL> select sysdate from dual;
  
  SYSDATE
  
  ---------
  
  01-JAN-03
  
  SQL> select systimestamp from dual;
  
  SYSTIMESTAMP
  
  ---------------------------------------------------------
  
  09-JUL-03 11.05.02.519000 AM -06:00
  
  当使用date和timestamp类型的时候,选择是很清楚的。你可以随意处置date和timestamp类型。当你试图转换到更强大的timestamp的时候,需要注意,它们既有类似的地方,更有不同的地方,而足以造成破坏。两者在简洁和间隔尺寸方面各有优势,请合理地选择。


原创粉丝点击