12
返回列表 发新帖
楼主: shengang34

mysql笔记--和oracle对比学习

[复制链接]
论坛徽章:
14
会员2007贡献徽章
日期:2007-09-26 18:42:10生肖徽章2007版:鸡
日期:2009-10-29 16:15:30生肖徽章2007版:兔
日期:2009-04-14 19:32:34生肖徽章2007版:猴
日期:2008-11-28 10:39:32奥运会纪念徽章:摔跤
日期:2008-08-12 10:59:32奥运会纪念徽章:艺术体操
日期:2008-08-07 09:43:42奥运会纪念徽章:举重
日期:2008-05-04 17:12:35生肖徽章2007版:鼠
日期:2008-01-02 17:35:53生肖徽章2007版:牛
日期:2008-01-02 17:35:53生肖徽章2007版:虎
日期:2008-01-02 17:35:53
11#
发表于 2007-11-2 13:47 | 只看该作者
希望有后续

使用道具 举报

回复
论坛徽章:
1
ITPUB新首页上线纪念徽章
日期:2007-10-20 08:38:44
12#
发表于 2007-11-4 21:23 | 只看该作者
楼主,你好。看到你在帖子里说,<b>“32位的操作系统有2G的文件限制”</b>,请问为什么有这样的限制呢?如果大于两G的话怎么处理呢,还有这个文件大小限制可有什么资料可以学习下,谢谢!

使用道具 举报

回复
论坛徽章:
10
会员2007贡献徽章
日期:2007-09-26 18:42:102011新春纪念徽章
日期:2011-02-18 11:43:342010广州亚运会纪念徽章:帆船
日期:2010-11-13 17:33:442010年世界杯参赛球队:科特迪瓦
日期:2010-10-08 11:21:35ITPUB9周年纪念徽章
日期:2010-10-08 09:31:222009日食纪念
日期:2009-07-22 09:30:00生肖徽章2007版:猴
日期:2008-01-02 17:35:53生肖徽章2007版:鸡
日期:2008-01-02 17:35:53ITPUB新首页上线纪念徽章
日期:2007-10-20 08:38:44ITPUB十周年纪念徽章
日期:2011-11-01 16:20:28
13#
 楼主| 发表于 2007-11-5 09:36 | 只看该作者
最初由 w_jack@126.com 发布
[B]楼主,你好。看到你在帖子里说,<b>“32位的操作系统有2G的文件限制”</b>,请问为什么有这样的限制呢?如果大于两G的话怎么处理呢,还有这个文件大小限制可有什么资料可以学习下,谢谢! [/B]




多谢提醒,这里有点错误,每个OS和文件系统的大小限制是不一样的,下面列出了几种常见操作系统的最大物理文件限制, 有的还需要在OS端设置大的文件系统和特定的环境变量等.
  
  Windows NT Maximum 4Gb files on FAT
  Theoretical 16Tb on NTFS
  
  
  Sun Solaris    ~~~~~~~~~
  Release Max file-system size Max OS File size
  < Solaris 2.6 1Tb (UFS) 2Gb
  >= Solaris 2.6 1Tb (40 bits) 1Tb   
  
   HPUX Unix Limits
  ~~~~~~~~~~~~~~~~~
  Max file system size:
  <= HP-UX 10.10 4Gb
  >= HP-UX 10.20 128Gb
  >= HP-UX 11.00 1Tb
  
  Max OS file size:
  <= HP-UX 10.10 2Gb
  >= HP-UX 10.20 128Gb
  >= HP-UX 11.00 1Tb

LINUX的最大CPU、内存、文件系统限制。
Intel X86

.最大CPU数: 32(包括逻辑CPU)
.最大内存: 64GB
.最大文件大小: 8TB
.最大文件系统大小(ext3): 16TB
.最大每个进程的虚拟地址空间: 4GB

AMD 64/EM64T

.最大CPU数: 64
.最大内存: 128GB
.最大文件大小: 8TB
.最大文件系统大小(ext3): 16TB
.最大每个进程的虚拟地址空间: N/A



  

使用道具 举报

回复
论坛徽章:
10
会员2007贡献徽章
日期:2007-09-26 18:42:102011新春纪念徽章
日期:2011-02-18 11:43:342010广州亚运会纪念徽章:帆船
日期:2010-11-13 17:33:442010年世界杯参赛球队:科特迪瓦
日期:2010-10-08 11:21:35ITPUB9周年纪念徽章
日期:2010-10-08 09:31:222009日食纪念
日期:2009-07-22 09:30:00生肖徽章2007版:猴
日期:2008-01-02 17:35:53生肖徽章2007版:鸡
日期:2008-01-02 17:35:53ITPUB新首页上线纪念徽章
日期:2007-10-20 08:38:44ITPUB十周年纪念徽章
日期:2011-11-01 16:20:28
14#
 楼主| 发表于 2007-11-5 11:51 | 只看该作者
十五、数据类型(数字、字符、日期,只打算介绍这3种最常用的)

15.1  数字
oracle
number(p,s),再次P,S是可选的,用于指定:

精度(precision),总位数。默认38位,可以在1 - 38之间。
小数位(scale),小数点右边的位数。-84 - 127之间,默认取决于精度,如果没指定精度,默认最大;指定了精度,默认0.

如果超出精度,就会报错,例如

oracle>create table t(num number(5,0));
Table created.

oracle>insert into t values(12345);
1 row created.

oracle>insert into t values(123456);
insert into t values(123456)
                     *
ERROR at line 1:
ORA-01438: value larger than specified precision allows for this column


oracle>insert into t values(12345.6);
1 row created.

oracle>insert into t values(12345.65655);
1 row created.

oracle>select * from t
  2  ;

       NUM
----------
     12345
     12346
     12346

总位数是5位,小数点为0,四舍五入。

oracle>create table t2(num number(5,2));
Table created.

oracle>insert into t2 values(12345);
insert into t2 values(12345)
                      *
ERROR at line 1:
ORA-01438: value larger than specified precision allows for this column

oracle>insert into t2 values(123.45);
1 row created.

oracle>insert into t2 values(123.456);
1 row created.

oracle>select * from t2;

       NUM
----------
    123.45
    123.46

指定小数为2位,所以整数为最多就为5-2=3位了。下面在测试下小数为负数的情况:

oracle>create table t3(num number(5,-2));
Table created.

oracle>insert into t3 values(123.45);
1 row created.

oracle>insert into t3 values(123.456);
1 row created.

oracle>insert into t3 values(1234567);
1 row created.

oracle>insert into t3 values(12345678);
insert into t3 values(12345678)
                      *
ERROR at line 1:
ORA-01438: value larger than specified precision allows for this column


oracle>select * from t3;
       NUM
----------
       100
       100
   1234600

小数位为负数,数位就是5-(-2)=7位了,在小数位左边四舍五入。


mysql提供了五种整型: tinyint、smallint、mediumint、int和bigint。int为integer的缩写。这些类型在可表示的取值范围上是不同的。整数列可定义为unsigned从而禁用负值;这使列的取值范围为0以上。各种类型的存储量需求也是不同的。取值范围较大的类型所需的存储量较大。
mysql 提供三种浮点类型: float、double和decimal。与整型不同,浮点类型不能是unsigned的,其取值范围也与整型不同,这种不同不仅在于这些类型有最大值,而且还有最小非零值。最小值提供了相应类型精度的一种度量,这对于记录科学数据来说是非常重要的(当然,也有负的最大和最小值)。

类型 说明

tinyint[(m)] 非常小的整数 ,有符号值:-128 到127(- 27 到27 - 1),无符号值:0到255(0 到28 - 1)

smallint[(m)] 较小整数 ,有符号值:-32768 到32767(- 215 到215 - 1),无符号值:0到65535(0 到21 6 - 1)

mediumint[(m)] 中等大小整数,有符号值:-8388608 到8388607(- 22 3 到22 3 - 1 ),无符号值:0到16777215(0 到22 4 - 1)

int[(m)] 标准整数,有符号-2147683648到2147683647(- 231 到231- 1),无符号值:0到4294967295(0 到232 - 1)

bigint[(m)] 较大整数,有符号值:-9223372036854775808 到9223373036854775807(- 263到263-1),无符号值:0到18446744073709551615(0到264 – 1)

float[(m, d)] 单精度浮点数,最小非零值:±1.175494351e - 38

double[(m, d)] 双精度浮点数,最小非零值:±2.2250738585072014e - 308

decimal[(m, d)] 一个串的浮点数,可变;其值的范围依赖于m 和d,m 的值应该取1 到255。d的值可为0 到3 0,但是不应大于m - 2

例如:

mysql> create table t(num int(5));
Query OK, 0 rows affected (0.06 sec)

mysql> insert into t values(12345);
Query OK, 1 row affected (0.03 sec)

mysql> insert into t values(123456);
Query OK, 1 row affected (0.03 sec)

mysql> insert into t values(123.456);
Query OK, 1 row affected (0.03 sec)

mysql> insert into t values(1234.56);
Query OK, 1 row affected (0.03 sec)

mysql> select * from t;
+--------+
| num    |
+--------+
|  12345 |
| 123456 |
|    123 |
|   1235 |
+--------+
4 rows in set (0.00 sec)



int(5)和oracle的number(5)不一样。这个可选的宽度规格说明是用于在数值显示时,对某些值的宽度短于该列宽度的值进行左填补显示的,而不是为了限制在该列中存储值的宽度,也不是为了限制那些超过该列指定宽度的值的可被显示的数字位数。
如果有小数位,将自动四舍五入。




mysql> create table t2(num dec(5,2));
Query OK, 0 rows affected (0.06 sec)

mysql> insert into t2 values(12345);
ERROR 1264 (22003): Out of range value for column 'num' at row 1

mysql> insert into t2 values(123.45);
Query OK, 1 row affected (0.03 sec)

mysql> insert into t2 values(123.456);
Query OK, 1 row affected, 1 warning (0.03 sec)

mysql> select * from t2;
+--------+
| num    |
+--------+
| 123.45 |
| 123.46 |
+--------+
2 rows in set (0.00 sec)

ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for
the right syntax to use near '-2))' at line 1

使用浮点数dec(m,d),和oracle的number(p,s)的功能一样,表示精度和小数位。至于怎么在小数点左边四舍五入,我没找到方法。

使用道具 举报

回复
论坛徽章:
14
会员2007贡献徽章
日期:2007-09-26 18:42:10生肖徽章2007版:鸡
日期:2009-10-29 16:15:30生肖徽章2007版:兔
日期:2009-04-14 19:32:34生肖徽章2007版:猴
日期:2008-11-28 10:39:32奥运会纪念徽章:摔跤
日期:2008-08-12 10:59:32奥运会纪念徽章:艺术体操
日期:2008-08-07 09:43:42奥运会纪念徽章:举重
日期:2008-05-04 17:12:35生肖徽章2007版:鼠
日期:2008-01-02 17:35:53生肖徽章2007版:牛
日期:2008-01-02 17:35:53生肖徽章2007版:虎
日期:2008-01-02 17:35:53
15#
发表于 2007-11-6 09:22 | 只看该作者
持续关注

使用道具 举报

回复
论坛徽章:
10
会员2007贡献徽章
日期:2007-09-26 18:42:102011新春纪念徽章
日期:2011-02-18 11:43:342010广州亚运会纪念徽章:帆船
日期:2010-11-13 17:33:442010年世界杯参赛球队:科特迪瓦
日期:2010-10-08 11:21:35ITPUB9周年纪念徽章
日期:2010-10-08 09:31:222009日食纪念
日期:2009-07-22 09:30:00生肖徽章2007版:猴
日期:2008-01-02 17:35:53生肖徽章2007版:鸡
日期:2008-01-02 17:35:53ITPUB新首页上线纪念徽章
日期:2007-10-20 08:38:44ITPUB十周年纪念徽章
日期:2011-11-01 16:20:28
16#
 楼主| 发表于 2007-11-7 10:16 | 只看该作者
15.2  字符串

15.2.1 文本字符串
mysql    char,varchar
CHAR列的长度固定为创建表时声明的长度。长度可以为从0到255的任何值。当保存CHAR值时,在它们的右边填充空格以达到指定的长度。当检

索到CHAR值时,尾部的空格被删除掉。在存储或检索过程中不进行大小写转换。
VARCHAR列中的值为可变长字符串。长度可以指定为0到65,535之间的值。(VARCHAR的最大有效长度由最大行大小和使用的字符集确定。整体最

大长度是65,532字节)。
同CHAR对比,VARCHAR值保存时只保存需要的字符数,另加一个字节来记录长度(如果列声明的长度超过255,则使用两个字节)。

oracle   char,varchar2

和mysql的一样,只不过oraclec的char 长度最大2000,varchar2长度最大4000。mysql当检索到CHAR值时,尾部的空格被删除掉,oracle不会。

我们在应用中应当尽量避免使用char,因为char总是会用空格填充得到的串,占用大量空间,而且还会带来混乱。举例说明:

oracle>create table t(char_col char(20),varchar2_col varchar2(20));
Table created.

oracle>insert into t values('hello','hello');
1 row created.

oracle>select * from t;
CHAR_COL                                 VARCHAR2_COL
---------------------------------------- ----------------------------------------
hello                                    hello

oracle>select * from t where char_col='hello';
CHAR_COL                                 VARCHAR2_COL
---------------------------------------- ----------------------------------------
hello                                    hello

oracle>select * from t where varchar2_col='hello';
CHAR_COL                                 VARCHAR2_COL
---------------------------------------- ----------------------------------------
hello                                    hello

这样看上去没有问题,但实际char列后面被空格填充了,在查询的时候发生了隐式转换,下面查询可以看出

oracle>select * from t where char_col=varchar2_col;
no rows selected

截去空格可以查出,如下

oracle>select * from t where trim(char_col)=varchar2_col;

CHAR_COL                                 VARCHAR2_COL
---------------------------------------- ----------------------------------------
hello                                    hello

在mysql下,情况不是这样,因为检索时从CHAR列自动删除了尾部。

mysql> create table t(char_col char(20),varchar2_col varchar(20));
Query OK, 0 rows affected (0.08 sec)

mysql> insert into t values('hello','hello');
Query OK, 1 row affected (0.03 sec)

mysql> insert into t values('hello ','hello ');
Query OK, 1 row affected (0.03 sec)

mysql> select * from t where char_col=varchar2_col;
+----------+--------------+
| char_col | varchar2_col |
+----------+--------------+
| hello    | hello        |
| hello    | hello        |
+----------+--------------+
2 rows in set (0.00 sec)



mysql当检索到CHAR值时,尾部的空格被删除掉,oracle不会,下面这个查询更加直观:

mysql> select concat(char_col,'+'),concat(varchar2_col,'+') from t;
+----------------------+--------------------------+
| concat(char_col,'+') | concat(varchar2_col,'+') |
+----------------------+--------------------------+
| hello+               | hello+                   |
| hello+               | hello +                  |
+----------------------+--------------------------+
2 rows in set (0.00 sec)


oracle>insert into t values('hello ','hello ');
1 row created.

oracle>select concat(char_col,'+'),concat(varchar2_col,'+') from t;

CONCAT(CHAR_COL,'+')                       CONCAT(VARCHAR2_COL,'+')
------------------------------------------ ------------------------------------------
hello               +                      hello+
hello               +                      hello +

当需要存储的文本字符串超过varchar的最大限制时怎么办呢?mysql可以使用xxxTEXT类型、oracle可以使用clob类型来处理大量的文本信息。

具体就不详细介绍了。



15.2.2  二进制字符


raw(size),最多2000字节限制。raw与varchar2类型很相似,是一个变长的二进制串。例如

oracle>create table t(raw_data raw(8));
Table created.

oracle>insert into t values ('1234');
1 row created.

oracle>insert into t values ('0123456789abcdef');
1 row created.

最大字节数是8,也就是16个字符

oracle>insert into t values ('0123456789abcdef1');
insert into t values ('0123456789abcdef1')
                      *
ERROR at line 1:
ORA-01401: inserted value too large for column

你会发现在处理RAW数据的时候,它将被隐式地转化为一个varchar2类型,也就是说,诸如sql*plus之类的许多工具不会直接显示RAW数据,而

是将其转换为一种十六进制的格式来显示。当然,在插入数据的时候也会隐式转换。

例如上面,如果插入非16进制字符的串,就会报错:

oracle>insert into t values ('gh');
insert into t values ('gh')
                      *
ERROR at line 1:
ORA-01465: invalid hex number

当然,也可以使用内置函数来显示,这是写代码很好的习惯。

hextoraw:将16进制字符串转换为raw类型
rawtohex:将raw串转化为16进制

例如:
oracle>insert into t values (hextoraw('abcd'));
1 row created.

bin(n),二进制数据,n,表示二进制位的个数(最大64),测试如下:

mysql> create table t(bit_data bit(8));
Query OK, 0 rows affected (0.09 sec)

mysql> insert into t values('a');
Query OK, 1 row affected (0.03 sec)

mysql> select bin(bit_data+0) from t;
+-----------------+
| bin(bit_data+0) |
+-----------------+
| 1100001         |
+-----------------+
1 row in set (0.00 sec)

mysql> create table t2(bit_data bit(4));
Query OK, 0 rows affected (0.08 sec)

mysql> insert into t2 values('a');
ERROR 1406 (22001): Data too long for column 'bit_data' at row 1

在当前的字符集下,字符串a转化为二进制是1100001七位,所以当bit(4)时,插入数据会报错。和oracle不同,mysql在处理二进制数据时,也

会隐式转换,不过不是转换为16进制,而是直接转换成字符串。


当处理大的二进制数据时,raw和bit类型显然是不够,可以使用blob来满足。这里也不做多的介绍了,感觉自己的理解也不是很透彻,特别是

做数据库迁移的时候,这种数据是最麻烦的。

使用道具 举报

回复
论坛徽章:
14
会员2007贡献徽章
日期:2007-09-26 18:42:10生肖徽章2007版:鸡
日期:2009-10-29 16:15:30生肖徽章2007版:兔
日期:2009-04-14 19:32:34生肖徽章2007版:猴
日期:2008-11-28 10:39:32奥运会纪念徽章:摔跤
日期:2008-08-12 10:59:32奥运会纪念徽章:艺术体操
日期:2008-08-07 09:43:42奥运会纪念徽章:举重
日期:2008-05-04 17:12:35生肖徽章2007版:鼠
日期:2008-01-02 17:35:53生肖徽章2007版:牛
日期:2008-01-02 17:35:53生肖徽章2007版:虎
日期:2008-01-02 17:35:53
17#
发表于 2007-11-8 10:07 | 只看该作者
嘿嘿
又更新了

使用道具 举报

回复
论坛徽章:
113
生肖徽章:牛
日期:2007-09-26 12:33:05马上有车
日期:2014-02-18 16:41:112014年新春福章
日期:2014-02-18 16:41:112013年新春福章
日期:2013-02-25 14:51:242012新春纪念徽章
日期:2012-01-04 11:49:542011新春纪念徽章
日期:2011-05-11 14:23:372010新春纪念徽章
日期:2010-01-04 22:00:09生肖徽章2007版:牛
日期:2009-09-18 22:19:58生肖徽章2007版:虎
日期:2009-05-19 22:37:22生肖徽章2007版:鼠
日期:2009-03-16 13:02:24
18#
发表于 2007-11-8 12:41 | 只看该作者
真的不错

使用道具 举报

回复
论坛徽章:
10
会员2007贡献徽章
日期:2007-09-26 18:42:102011新春纪念徽章
日期:2011-02-18 11:43:342010广州亚运会纪念徽章:帆船
日期:2010-11-13 17:33:442010年世界杯参赛球队:科特迪瓦
日期:2010-10-08 11:21:35ITPUB9周年纪念徽章
日期:2010-10-08 09:31:222009日食纪念
日期:2009-07-22 09:30:00生肖徽章2007版:猴
日期:2008-01-02 17:35:53生肖徽章2007版:鸡
日期:2008-01-02 17:35:53ITPUB新首页上线纪念徽章
日期:2007-10-20 08:38:44ITPUB十周年纪念徽章
日期:2011-11-01 16:20:28
19#
 楼主| 发表于 2007-11-12 10:16 | 只看该作者
15.3 时间数据

这一块很不好说清楚,也不打算把所有的时间类型列出来,只把主要的类型列出来。以下的都是自己的观点,如果有错误请指出。

MySQL日期和时间类型
· DATE
日期。支持的范围为'1000-01-01'到'9999-12-31'。MySQL以'YYYY-MM-DD'格式显示DATE值,但允许使用字符串或数字为DATE列分配值。

· DATETIME
日期和时间的组合。支持的范围是'1000-01-01 00:00:00'到'9999-12-31 23:59:59'。MySQL以'YYYY-MM-DD HH:MM:SS'格式显示DATETIME值,

但允许使用字符串或数字为DATETIME列分配值。

curdate()返回日期型数据 'YYYY-MM-DD'
now()返回日期时间型数据 'YYYY-MM-DD HH:MM:SS'

· TIMESTAMP[(M)]
时间戳。范围是'1970-01-01 00:00:00'到2037年。

TIMESTAMP列用于INSERT或UPDATE操作时记录日期和时间。如果你不分配一个值,表中的第一个TIMESTAMP列自动设置为最近操作的日期和时间

。也可以通过分配一个NULL值,将TIMESTAMP列设置为当前的日期和时间。TIMESTAMP值返回后显示为'YYYY-MM-DD HH:MM:SS'格式的字符串,显

示宽度固定为19个字符。如果想要获得数字值,应在TIMESTAMP 列添加+0。

例子:
mysql> insert into t(test_date,test_datetime,test_timestamp) values(curdate(),now(),null);
Query OK, 1 row affected (0.03 sec)

mysql> select * from t;
+----+------------+---------------------+---------------------+
| id | test_date  | test_datetime       | test_timestamp      |
+----+------------+---------------------+---------------------+
|  1 | 2007-11-02 | 2007-11-02 14:37:31 | 2007-11-02 14:37:31 |
+----+------------+---------------------+---------------------+
1 row in set (0.02 sec)

mysql> insert into t(test_date,test_datetime,test_timestamp) values(curdate(),now(),null);
Query OK, 1 row affected (0.03 sec)

mysql> insert into t(test_date,test_datetime,test_timestamp) values(curdate(),now(),null);
Query OK, 1 row affected (0.03 sec)

mysql> insert into t(test_date,test_datetime,test_timestamp) values(curdate(),now(),null);
Query OK, 1 row affected (0.08 sec)

mysql> insert into t(test_date,test_datetime) values(curdate(),now());
Query OK, 1 row affected (0.05 sec)

mysql> select * from t;
+----+------------+---------------------+---------------------+
| id | test_date  | test_datetime       | test_timestamp      |
+----+------------+---------------------+---------------------+
|  1 | 2007-11-02 | 2007-11-02 14:37:31 | 2007-11-02 14:37:31 |
|  2 | 2007-11-02 | 2007-11-02 14:37:44 | 2007-11-02 14:37:44 |
|  3 | 2007-11-02 | 2007-11-02 14:37:46 | 2007-11-02 14:37:46 |
|  4 | 2007-11-02 | 2007-11-02 14:37:48 | 2007-11-02 14:37:48 |
|  5 | 2007-11-02 | 2007-11-02 14:38:15 | 2007-11-02 14:38:15 |
+----+------------+---------------------+---------------------+
5 rows in set (0.00 sec)

mysql> select id,test_date,test_datetime,test_timestamp+0 from t;
+----+------------+---------------------+------------------+
| id | test_date  | test_datetime       | test_timestamp+0 |
+----+------------+---------------------+------------------+
|  1 | 2007-11-02 | 2007-11-02 14:37:31 |   20071102143731 |
|  2 | 2007-11-02 | 2007-11-02 14:37:44 |   20071102143744 |
|  3 | 2007-11-02 | 2007-11-02 14:37:46 |   20071102143746 |
|  4 | 2007-11-02 | 2007-11-02 14:37:48 |   20071102143748 |
|  5 | 2007-11-02 | 2007-11-02 14:38:15 |   20071102143815 |
+----+------------+---------------------+------------------+

mysql> insert into t(test_date,test_datetime) values('1999-12-22','1999-12-22');
Query OK, 1 row affected (0.03 sec)

mysql> select id,test_date,test_datetime,test_timestamp+0 from t;
+----+------------+---------------------+------------------+
| id | test_date  | test_datetime       | test_timestamp+0 |
+----+------------+---------------------+------------------+
|  1 | 2007-11-02 | 2007-11-02 14:37:31 |   20071102143731 |
|  2 | 2007-11-02 | 2007-11-02 14:37:44 |   20071102143744 |
|  3 | 2007-11-02 | 2007-11-02 14:37:46 |   20071102143746 |
|  4 | 2007-11-02 | 2007-11-02 14:37:48 |   20071102143748 |
|  5 | 2007-11-02 | 2007-11-02 14:38:15 |   20071102143815 |
|  6 | 1999-12-22 | 1999-12-22 00:00:00 |   20071102145216 |
+----+------------+---------------------+------------------+
6 rows in set (0.00 sec)

· TIME
时间。范围是'-838:59:59'到'838:59:59'。MySQL以'HH:MM:SS'格式显示TIME值,但允许使用字符串或数字为TIME列分配值。

· YEAR[(2|4)]
两位或四位格式的年。默认是四位格式。在四位格式中,允许的值是1901到2155和0000。在两位格式中,允许的值是70到69,表示从1970年到

2069年。MySQL以YYYY 格式显示YEAR值,但允许使用字符串或数字为YEAR列分配值。


oracle的时间类型,date,timestamp和interval.

oracle的date类型就相当于mysql的date+datetime的集合。

timestamp和mysql的timestamp是完全不同的概念,oracle的timestamp是date的扩张,支持时区和小数秒,精度默认值是6,即6位的小数秒。

interval固定的时间量,INTERVAL YEAR TO MONTH,INTERVAL DAY TO SECOND,YEAR精度默认值是2,DAY是2,SECOND是6。这个类型mysql没有




oracle>create table t(t_date date,t_timestamp timestamp,t_interval  INTERVAL YEAR TO MONTH);
Table created.

oracle>insert into t values(sysdate,systimestamp,numtoyminterval(5,'year'));
1 row created.

oracle>select * from t;
T_DATE    T_TIMESTAMP                    T_INTERVAL
--------- ------------------------------ ------------------------------
05-NOV-07 05-NOV-07 03.27.34.698096 PM   +05-00


oracle>insert into t values('1999-12-22','1999-12-22',numtoyminterval(5,'year'));
insert into t values('1999-12-22','1999-12-22',numtoyminterval(5,'year'))
                     *
ERROR at line 1:
ORA-01861: literal does not match format string

oracle不能像myslq一样把字符自动转化为日期格式,必须使用函数

oracle提供了一些有用的函数来完成字符串和日期类型之间的转换:

TO_DATE
TO_TIMESTAMP
TO_TIMESTAMP_TZ
TO_YMINTERVAL
TO_DSINTERVAL
NUMTOYMINTERVAL
NUMTODSINTERVAL
TO_CHAR

函数的使用可以查手册。


oracle>insert into t values(to_date('1999-12-22 14:30:00','yyyy-mm-dd hh24:mi:ss'),to_timestamp('1999-12-22

14:30:30.45','yyyy-mm-dd hh24:mi:ss.ff'),null);

1 row created.

oracle>select * from t;

T_DATE    T_TIMESTAMP                    T_INTERVAL
--------- ------------------------------ ------------------------------
05-NOV-07 05-NOV-07 03.34.38.344712 PM   +05-00
22-DEC-99 22-DEC-99 02.30.30.450000 PM


显示不是我们想要的格式,可以根据自己的需要使用to_char函数。

oracle>select to_char(t_date,'yyyy-mm-dd hh24:mi:ss') t_date,to_char(t_timestamp,'yyyy-mm-dd hh24:mi:ss:ff')

t_timestamp,t_interval from t;

T_DATE                                 T_TIMESTAMP                              T_INTERVAL
-------------------------------------- ---------------------------------------- ------------------------------
2007-11-05 15:34:38                    2007-11-05 15:34:38:344712               +05-00
1999-12-22 14:30:00                    1999-12-22 14:30:30:450000



可能我们实际中用的很多的是需要得到2个时间之差,这2个数据库都有自己的函数来实现:

mysql> create table t3(date1 datetime,date2 datetime);
Query OK, 0 rows affected (0.16 sec)

mysql> insert into t3 values('1999-12-22 14:30:00',now());
Query OK, 1 row affected (0.08 sec)

mysql> select * from t3;
+---------------------+---------------------+
| date1               | date2               |
+---------------------+---------------------+
| 1999-12-22 14:30:00 | 2007-11-06 10:47:25 |
+---------------------+---------------------+
1 row in set (0.00 sec)

mysql> insert into t3 values('2007-10-21 14:30:00',now());
Query OK, 1 row affected (0.06 sec)

mysql> select timediff(date2,date1) from t3;
+-----------------------+
| timediff(date2,date1) |
+-----------------------+
| 838:59:59             |
| 380:34:01             |
+-----------------------+
2 rows in set, 1 warning (0.00 sec)

mysql> select * from t3;
+---------------------+---------------------+
| date1               | date2               |
+---------------------+---------------------+
| 1999-12-22 14:30:00 | 2007-11-06 10:47:25 |
| 2007-10-21 14:30:00 | 2007-11-06 11:04:01 |
+---------------------+---------------------+
2 rows in set (0.00 sec)

mysql> insert into t3 values('2000-10-21 14:30:00',now());
Query OK, 1 row affected (0.03 sec)

mysql> select * from t3;
+---------------------+---------------------+
| date1               | date2               |
+---------------------+---------------------+
| 1999-12-22 14:30:00 | 2007-11-06 10:47:25 |
| 2007-10-21 14:30:00 | 2007-11-06 11:04:01 |
| 2000-10-21 14:30:00 | 2007-11-06 11:05:47 |
+---------------------+---------------------+
3 rows in set (0.00 sec)

mysql> select date2-date1 from t3;
+--------------------+
| date2-date1        |
+--------------------+
| 79883961725.000000 |
|    84967401.000000 |
| 70084967547.000000 |
+--------------------+
3 rows in set (0.00 sec)

这个看不太明白什么意思。。。

mysql> select timediff(date2,date1) from t3;
+-----------------------+
| timediff(date2,date1) |
+-----------------------+
| 838:59:59             |
| 380:34:01             |
| 838:59:59             |
+-----------------------+
3 rows in set, 2 warnings (0.02 sec)


838:59:59这个时间差明显是不对的,估计是timediff函数的一个上限值,也就是说超过这个差距timediff函数就不能正确使用。

mysql> SELECT UNIX_TIMESTAMP(date2)-UNIX_TIMESTAMP(date1) from t3;
+---------------------------------------------+
| UNIX_TIMESTAMP(date2)-UNIX_TIMESTAMP(date1) |
+---------------------------------------------+
|                                   248473045 |
|                                     1370041 |
|                                   222208547 |
+---------------------------------------------+
3 rows in set (0.00 sec)

秒数是对的,但是显然我们不想看到这样的结果,这样的结果我我们没有任何意义,但是怎么转化成时间差多少年、月、日、小时呢?

mysql> SELECT SEC_TO_TIME(UNIX_TIMESTAMP(date2)-UNIX_TIMESTAMP(date1)) from t3;
+----------------------------------------------------------+
| SEC_TO_TIME(UNIX_TIMESTAMP(date2)-UNIX_TIMESTAMP(date1)) |
+----------------------------------------------------------+
| 838:59:59                                                |
| 380:34:01                                                |
| 838:59:59                                                |
+----------------------------------------------------------+
3 rows in set, 2 warnings (0.00 sec)

结果和timediff一样,难道是mysql数据库的限制?是的,前面我们介绍了

· TIME
时间。范围是'-838:59:59'到'838:59:59'。MySQL以'HH:MM:SS'格式显示TIME值,但允许使用字符串或数字为TIME列分配值。


oracle中如何得到时间差?

oracle>create table t3(date1 date,date2 date);
Table created.

oracle>insert into t3 values(to_date('1999-12-22 14:30:00','yyyy-mm-dd hh24:mi:ss'),sysdate);
1 row created.

oracle>insert into t3 values(to_date('2007-10-21 14:30:00','yyyy-mm-dd hh24:mi:ss'),sysdate);
1 row created.

oracle>insert into t3 values(to_date('2000-10-21 14:30:00','yyyy-mm-dd hh24:mi:ss'),sysdate);
1 row created.

oracle>select to_char(date1,'yyyy-mm-dd hh24:mi:ss') date1,to_char(date2,'yyyy-mm-dd hh24:mi:ss') date2 from t3;

DATE1                                  DATE2
-------------------------------------- --------------------------------------
1999-12-22 14:30:00                    2007-11-07 10:34:06
2007-10-21 14:30:00                    2007-11-07 10:35:25
2000-10-21 14:30:00                    2007-11-07 10:35:55


oracle>select date2-date1 from t3;

DATE2-DATE1
-----------
2876.83618
16.8370949
2572.83744

数据是没错,但是也不是我们想要的格式。


oracle>select months_between(date2,date1) from t3;

MONTHS_BETWEEN(DATE2,DATE1)
---------------------------
                 94.5108445
                 .543132094
                 84.5431433
也一样。


oracle>select numtoyminterval(months_between(date2,date1),'month') years_months,numtodsinterval(date2-add_months(date1,trunc

(months_between(date2,date1))),'day') days_hours from t3;

YEARS_MONTHS                   DAYS_HOURS
------------------------------ ---------------------------------------------------------------------------
+000000007-10                  +000000015 20:04:06.000000000
+000000000-00                  +000000016 20:05:25.000000000
+000000007-00                  +000000016 20:05:55.000000000


OK,可以很明显,第一行记录是7年10个月15天20小时4分6秒。这里myslq没有的interval类型就起作用了。

使用道具 举报

回复

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

本版积分规则 发表回复

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