1.char的最大长度
一直记得char的最大长度是255字节,varchar2是4000字节,结果今天看oracle 9i的SQL Reference,发现错了,char的最大长度是2000。 想想原因,可能是和informix的char和varchar长度记混了。informix里面varchar是255,char的最大是32767,但是实际上和整行大小有关系,整行大小不能超过32767,也就是说如果这个表只有一个char的字段,那最大就可以到32767,否则肯定就没有了,其他字段还要占一定的长度呢。
呵呵,写着写着,倒是像informix的学习笔记了,唉,谁叫俺们的项目既要支持oracle,又要支持informix呢。
2.char和varchar的单位
可以是字节为单位,也可以是字符为单位。
一个字符可以是一个字节,也可以是多个字节,要看字符集是啥了。
SQL> create table tsttbl (a varchar2(10 byte), b varchar2(10 char));
Table created.
SQL> insert into tsttbl values('two apples', 'two apples');
1 row created.
SQL> insert into tsttbl values('two apples', 'two apples,three figs');
insert into tsttbl values('two apples', 'two apples,three figs')
*
ERROR at line 1:
ORA-01401: inserted value too large for column
SQL> insert into tsttbl values('two apples', '两个苹果和三个无花果');
1 row created.
再用length和lengthb函数来看看长度:
SQL> select length(a),length(b) from tsttbl;
LENGTH(A) LENGTH(B)
---------- ----------
10 10
10 10
SQL> select lengthb(a),lengthb(b) from tsttbl;
LENGTHB(A) LENGTHB(B)
---------- ----------
10 10
10 20
因为测试数据库的字符集为ZHS16GBK,一个汉字两个字节,因此lengthb看10个中文字符的长度就是20字节了。 用dump来看可能就更清楚了:
SQL> select dump(a),dump(b) from tsttbl;
DUMP(A)
--------------------------------------------------------------------------------------------
DUMP(B)
--------------------------------------------------------------------------------------------
Typ=1 Len=10: 116,119,111,32,97,112,112,108,101,115
Typ=1 Len=10: 116,119,111,32,97,112,112,108,101,115
Typ=1 Len=10: 116,119,111,32,97,112,112,108,101,115
Typ=1 Len=20: 193,189,184,246,198,187,185,251,186,205,200,253,184,246,206,222,187,168,185,251
根据上面的例子,可以看出byte和char的不同了,byte就是实际字节长度,而char是字符长度,所占字节长度和存储的字符及其字符集有关。
3. nchar和nvarchar2
这个数据类型在工作中基本没用过。看SQL Refernce的说明,其字段长度是以字符为单位的,而不是字节,最大长度仍然为2000和4000个字节。
这两个类型和char和varchar2还有一个很大的不同是,即使插入的是英文字符,所占字节还是根据字符集来算,比如在ZHS16GBK的情况下,所有插进去的字符,不管中文英文,都是占2个字节。
看例子:
SQL> create table tsttbl (a nvarchar2(10), b nchar(10));
Table created.
SQL> insert into tsttbl values('two apples', 'three figs');
1 row created.
SQL> insert into tsttbl values('two apples', '两个苹果和三个无花果');
1 row created.
SQL> select length(a),length(b) from tsttbl;
LENGTH(A) LENGTH(B)
---------- ----------
10 10
10 10
SQL> select lengthb(a),lengthb(b) from tsttbl;
LENGTHB(A) LENGTHB(B)
---------- ----------
20 20
20 20
SQL> select dump(a),dump(b) from tsttbl;
DUMP(A)
--------------------------------------------------------------------------------
DUMP(B)
--------------------------------------------------------------------------------
Typ=1 Len=20: 0,116,0,119,0,111,0,32,0,97,0,112,0,112,0,108,0,101,0,115
Typ=96 Len=20: 0,116,0,104,0,114,0,101,0,101,0,32,0,102,0,105,0,103,0,115
Typ=1 Len=20: 0,116,0,119,0,111,0,32,0,97,0,112,0,112,0,108,0,101,0,115
Typ=96 Len=20: 78,36,78,42,130,249,103,156,84,140,78,9,78,42,101,224,130,177,103
,156
不过文中有句话未理解: You cannot insert a CHAR value into an NCHAR column, nor can you insert an NCHAR value into a CHAR column.
我在上面的SQL之后再执行下面两句,没发现问题:
SQL> create table tsttbl2 (a varchar2(10 char), b char(10 char));
Table created.
SQL> insert into tsttbl2 select * from tsttbl;
2 rows created.