首页 > 代码库 > 前台页面验证中需要注意的一个与VARCHAR2(N BYTE)和VARCHAR2(N CHAR)的小细节

前台页面验证中需要注意的一个与VARCHAR2(N BYTE)和VARCHAR2(N CHAR)的小细节

1:一个小的测试实例

CREATE TABLE SALES.TEST_
(
  TEST_BYTE     VARCHAR2(5 BYTE),
  TEST_CHAR     VARCHAR2(5 CHAR)
)--TABLE CREATED

INSERT INTO TEST_ (TEST_CHAR) VALUES(12345)--1 ROW INSERTED

INSERT INTO TEST_ (TEST_BYTE) VALUES(12345)--1 ROW INSERTED

INSERT INTO TEST_ (TEST_CHAR) VALUES(abcde)--1 ROW INSERTED

INSERT INTO TEST_ (TEST_BYTE) VALUES(abcde)--1 ROW INSERTED

INSERT INTO TEST_ (TEST_CHAR) VALUES(@#$%&)--1 ROW INSERTED

INSERT INTO TEST_ (TEST_BYTE) VALUES(@#$%&)--1 ROW INSERTED

INSERT INTO TEST_ (TEST_CHAR) VALUES(1a@_好)--1 ROW INSERTED

INSERT INTO TEST_ (TEST_BYTE) VALUES(1a@_好)--ORA-12899: value too large for column "SALES"."TEST_"."TEST_BYTE" (actual: 7, maximum: 5)

INSERT INTO TEST_ (TEST_CHAR) VALUES(一二三四五)--1 ROW INSERTED

INSERT INTO TEST_ (TEST_BYTE) VALUES(一二三四五)--ORA-12899: value too large for column "SALES"."TEST_"."TEST_BYTE" (actual: 15, maximum: 5)

2:实例的说明

从上面的例子中我们已经看到了比较的明显的区别,对于VARCHAR2(5 BYTE)和VARCHAR2(5 CHAR)当插入的字符个数为五且其中有中文时或者是全是中文时就报错!所以在前台页面做有关长度的控制和验证时,必须注意!如果数据库中定义的是VARCHAR2(N CHAR),则定义的是几前台页面控制最大字符个数是几就行了,如果数据库中定义的是VARCHAR2(N BYTE),则必须根据数据库默认的字符集结合NLS_LENGTH_SEMANTICS的值和是否有可能输入中文来控制!上述实例报错的原因很明确,但是为什么报这样的错误呢?

首先要明确以下个点:

1)VARCHAR2(N CHAR)是指允许最大N个字符的存储,与BYTE的个数无关

2)VARCHAR2(5 BYTE)是指只允许最大N个BYTE长度的字符存储,和字符的个数无关

3)从9i开始,oracle提供了NLS_LENGTH_SEMANTICS这个参数,其有两个取值,CHAR和BYTE。当为CHAR时字符类型的长度是按字符个数来计算,而不是按BYTE来计算,这在使用变长字符集(AL32UTF8)的情况下非常有用,因为一个字符所占用的字节数是不定的,就给我们准确估计字段长度(BYTE)带来不便。同时当为CHAR时,对那些采用7/8bit的字符集(US7ASCII/WE8MSWIN1252)来说也不会带来空间上的浪费。

4)我的数据库是ORACLE 10 G NLS_LENGTH_SEMANTICS默认值是BYTE(如下图所示)

 

5)我的字符集是AMERICAN_AMERICA.AL32UTF8

SELECT USERENV(LANGUAGE) FROM DUAL--AMERICAN_AMERICA.AL32UTF8

或者使用下面的SQL语句查询

SELECT * FROM NLS_DATABASE_PARAMETERS;

6)对于AMERICAN_AMERICA.AL32UTF8字符集,一个汉字占三个字节,一个字母、数据或特殊字符占一个字节(实验显示)

根据以上六点需要明确的知识点,上面报错的原因就一目了然了!

参考:

1:http://www.2cto.com/database/201304/203337.html

2:http://blog.sina.com.cn/s/blog_69e55cc20100svty.html

3:http://www.oracle-base.com/articles/9i/character-semantics-and-globalization-9i.php