Oracle的数据类型介绍

本文简要介绍 Oracle 常用的基本数据类型及特点,包括字符类型LOB 类型数值类型日期类型

1 字符类型

字符类型是 Oracle 中基础数据类型之一,也是数据库开发中最常用的一种数据类型。

Oracle 提供了四种主要的字符类型:char、nchar、varchar2、nvarchar2。

1.1 char 和 varchar2

char 最大长度为 2000 字节,属于定长度类型,即 char(n)指定了字符串长度,n 介于 1 到 2000 之间,即使输入的字节数小于 n,也会用空格补足到 n 长度。例如:

1
l_char char(10):='test';

指定 l_char 的长度为 10,内容为“test”,但实际 l_char 存储的是“test”+六个空格。

varchar2 最大长度为 4000 字节,属于变长度类型,即 varchar2(n)指定了字符串长度,n 介于 1 到 4000 之间,如果输入的字节数小于 n,那么字符串长度等于实际输入长度。例如:

1
l_varchar2 varchar2(10):='test';

指定 l_varchar2 的长度为 10,内容为“test”,实际 l_varchar2 存储的也是四个字节的“test”。

很明显,varchar2 要更节省数据库空间,但为什么还要有 char 类型呢?因为 char 的定长度特性,在需要频繁修改的字段,使用 char 具有一定的效率优势。

char 牺牲空间,提高效率,但有一个弊端,在读取 char 数据时,需要用 trim()函数来去掉 char 补足的空格,否则获取的就是带着一串空格的内容。

1.2 nchar 和 nvarchar2

在学习了 char 和 varchar2 后,nchar 和 nvarchar2 就不难理解了。

以 nchar 为例,在 char 前加了一个“n”,所代表的意义就是以字符数确定长度,而非以字节数确定长度。例如:

1
l_char char(10):='1234567890';
1
l_nchar nchar(10):='一二三四五六七八九零';

l_char 指定的长度是 10 个字节,那么它只能存储不超过 10 个的数字、英文字母、英文符号,或者不超过 5 个的汉字或符号(这里指 GBK 编码,一个汉字两个字节,如果是 UTF-8 编码,则是一个汉字占三个字节)。

l_nchar 指定的长度是 10 个字符,那么它可以存储不超过 10 个的数字、英文字母、英文符号、汉字或符号。

nvarchar2 和 nchar 类似,是以字符数来确定长度的,二者适合存储汉字或符号。

与 char 和 varchar2 相同的是,nchar 和 nvarchar2 的最大长度分别是 2000 字节和 4000 字节。那么在 GBK 编码下,nchar(n)中的 n 最大是 1000,nvarchar2(n)中的 n 最大是 2000,否则就有可能超出字节限制,导致数据丢失。在 UTF-8 编码下,其最大字符长度则分别为 666 和 1333。

1.3 varchar2,4000 还是 32767?

在 PL/SQL 中,有时会见到类似如下语句:

1
l_varchar2 varchar2(32767);

有的同学会有疑问:前边不是说 varchar2 最大长度是 4000 字节吗?

这并不矛盾,4000 字节的长度限制,是存储在数据表中的 varchar2 字段的最大长度。

在 PL/SQL 的存储过程中,varchar2 类型变量的最大长度可达 32767 字节!

表字段 4000 字节,存储过程变量 32767 字节,不能更长了。

2 LOB 类型

在存储二进制数据时,要使用 BLOB 类型;

存储超过 4000 字节的字符型表字段,或使用超过 32767 字节的 PL/SQL 变量时,需要用到 CLOB 类型,CLOB 可以存储不超过 4GB 的字符内容。

注意:在非必要的情况下,尽量不使用 BLOB 或 CLOB,它会大大降低执行效率。

3 字符类型

3.1 NUMBER(P,S)

NUMBER(P,S)是最常见的数字类型,需要 1~22 字节(BYTE)不等的存储空间,可以存放数据范围为:

10^-130~10^126(不包含此值)

P 是 Precison 的英文缩写,即精度缩写,表示有效数字的位数,最多不能超过 38 个有效数字。

S 是 Scale 的英文缩写,可以使用的范围为-84~127。Scale 为正数时,表示从小数点到最低有效数字的位数,它为负数时,表示从最大有效数字到小数点的位数。

下面是官方文档的示例:

实际数据 定义类型 存储数据
123.89 NUMBER 123.89
123.89 NUMBER(3) 124
123.89 NUMBER(6,2) 123.89
123.89 NUMBER(6,1) 123.9
123.89 NUMBER(3) 124
123.89 NUMBER(4,2) 超出精度,无法存储
123.89 NUMBER(6,-2) 100
.01234 NUMBER(4,5) .01234
.00012 NUMBER(4,5) .00012
.000127 NUMBER(4,5) .00013
.0000012 NUMBER(2,7) .0000012
.00000123 NUMBER(2,7) .0000012
1.2e-4 NUMBER(2,5) 0.00012
1.2e-5 NUMBER(2,5) 0.00001

3.2 INTEGER 类型

INTEGER 是 NUMBER 的子类型,它等同于 NUMBER(38,0),用来存储整数。

INTEGER 的数值范围是-2147483648 到 2147483647 。

若 INTEGER 字段插入、更新的数值有小数,则会被四舍五入。

4 日期类型

DATE 是最常用的日期数据类型(本文不介绍 timestamp 相关内容),存储日期和时间信息。

DATE 类型可以转换成字符类型:

1
to_char(DATE,'YYYY/MM/DD HH24:MI:SS')

转换成类似’2018/01/29 22:13:42’的格式。

格式是可以自己定义的,也可以用:

1
to_char(DATE,'YYYY-MM-DD')

转换成类似’2018-01-29’的格式。

如果将 DATE 类型不经转换直接写入 VARCHAR2 字段,其格式是不可预知的,例如:

1
update tableA set varcharA=sysdate;

其中 varcharA 是 VARCHAR2 类型,sysdate 是 DATE 类型的系统当前时间,写入后,varcharA 字段可能是 2018-01-29 的格式,也可能是 29-1 月-18 的格式,可能是 Jan-29-18 的格式。

为了避免这种不可控,应使用 to_char 转换后再写入 VARCHAR2 字段:

1
update tableA set varcharA=to_char(sysdate,'YYYY-MM-DD');

同样,VARCHAR2 类型也可以通过 to_date 函数转换为 DATE 类型:

1
to_date('2018/01/29','YYYY-MM-DD')

转换成 2018 年 1 月 29 日 0 时 0 分 0 秒的 DATE 类型。

总之,DATE 类型包含的数据,包含年月日时分秒,它可以通过不同的形式显示出来,但它是精确到秒的一个特定的时间点。