xy_z487 发表于 2013-2-5 02:12:11

Oracle varchar2

何时该用CHAR,何时该用varchar2?
CHAR与VARCHAR2是一对矛盾的统一体,两者是互补的关系.
VARCHAR2比CHAR节省空间,在效率上比CHAR会稍微差一些,即要想获得效率,就必须牺牲一定的空间,这也就是我们在数据库设计上常说的‘以空间换效率’。
VARCHAR2虽然比CHAR节省空间,但是如果一个VARCHAR2列经常被修改,而且每次被修改的数据的长度不同,这会引起‘行迁移 ’(Row Migration)现象,而这造成多余的I/O,是数据库设计和调整中要尽力避免的,在这种情况下用CHAR代替VARCHAR2会更好一些。

这几天在做测试的时候发现一个异常:java.sql.SQLException: ORA-01401: inserted value too large for column。显然是插入的中文字符过长了。要插入的这个字段是varchar2类型的, oracle中varchar2最大是4000字节,按道理4000个字节可以插入2000个汉字的。有点迷惑。。。
   首先在一台win xp的数据库服务器上实验:
SQL> select * from v$version;

BANNER
----------------------------------------------------------------
Oracle9i Enterprise Edition Release 9.2.0.1.0 - Production
PL/SQL Release 9.2.0.1.0 - Production
CORE    9.2.0.1.0    Production
TNS for 32-bit Windows: Version 9.2.0.1.0 - Production
NLSRTL Version 9.2.0.1.0 - Production

SQL>
SQL> create table t ( c varchar2(4000));

表以创建.

SQL> insert into t values ('测试');

已创建1行。

SQL> commit;

--前面已经插入了2个汉字,这次再增加999*2个汉字。
SQL> begin
2 for i in 1..999 loop
3 update t set c=c||'测试';
4 commit;
5 end loop;
6 end;
7 /

PL/SQL 过程已成功完成。

SQL> select length(c) from t;

LENGTH(C)
----------
      2000

SQL> select lengthb(c) from t ;

LENGTHB(C)
----------
      4000

显然插入2000个汉字成功了

然后在另一台linux机器上实验:
sql->select * from V$version;
Oracle9i Enterprise Edition Release 9.2.0.4.0 - Production
PL/SQL Release 9.2.0.4.0 - Production
CORE    9.2.0.3.0    Production
TNS for Linux: Version 9.2.0.4.0 - Production

NLSRTL Version 9.2.0.4.0 - Production

SQL>
SQL> create table t ( c varchar2(4000));

表以创建.

SQL> insert into t values ('测试');

已创建1行。

SQL> commit;

然后:
begin
   for i in 1..999 loop
   update t set c=c||'测试';
commit;
end loop;
   end;
------------------------
begin
*
ERROR 位于第 1 行:
ORA-01489: result of string concatenation is too long
ORA-06512: at line 3
---------------------------
显然是太长了。。。

sql->select length(c) from t;
LENGTH(C)
----------
      1332

已选择 1 行。
sql->select lengthb(c) from t;
LENGTHB(C)
----------
      3996

已选择 1 行。

--------------
不清楚linux那台机器字符集是不是utf-8编码,如果是,那么上面的结果正常。utf-8中汉字是占3字节的。

具体为什么会这样,那位达人可以告诉我?

另外:length 与 lengthb 的区别,
          length求得是字符长度,
          lengthb求得是字节长度。

...

....

...
....
页: [1]
查看完整版本: Oracle varchar2