今天在数据库(10.2.0.5,字符集是ZHS16GBK)做一个测试,一张表上建一个varchar2(4000)的字段,然后select这张表for update,往该字段里复制汉字,结果发现最多只能复制进去1000个汉字,再多就报错ORA-01480:trailing null missing from STR bind value.dump了汉字看过,一个汉字占两字节。改用全英文,最大只能复制进去2000个字母。
    在网上找到一种解释是:在存储过程中varchar2可以传递4000个字符(2000个汉字),而在表结构中varchar2最多可以保存2000个字符(1000个汉字),所以虽然可以传递4000个字符,在保存到数据库中时,会自动截取。
    但是这种解释貌似官方文档上找不到,不知道是不是这么回事?

解决方案 »

  1.   

    SQL> create table t(nn varchar2(4000));表已创建。SQL> insert into t select rpad('一',2010,'二') from dual;已创建 1 行。SQL> select length(nn) from t;LENGTH(NN)
    ----------
          1005SQL> select lengthb(nn) from t;LENGTHB(NN)
    -----------
           2010
      

  2.   

    BANNER
    ----------------------------------------------------------------
    Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Prod
    PL/SQL Release 10.2.0.1.0 - Production
    CORE    10.2.0.1.0      Production
    TNS for 32-bit Windows: Version 10.2.0.1.0 - Production
    NLSRTL Version 10.2.0.1.0 - Production
      

  3.   

    这和你的字符集设置有关、没有谁规定一个字符等于两个汉字吧
    二楼那只是凑巧、以下是我的测试sys@ORCL> select * from sys.props$ where name='NLS_CHARACTERSET';NAME                 VALUE$     COMMENT$
    -------------------- ---------- --------------------
    NLS_CHARACTERSET     AL32UTF8   Character sethr@ORCL> drop table t purge;Table dropped.hr@ORCL> create table t(nn varchar2(4000));Table created.hr@ORCL> insert into t select rpad('一',2010,'二') from dual;1 row created.hr@ORCL> select lengthb(nn) from t;LENGTHB(NN)
    -----------
           3015hr@ORCL> select length(nn) from t;LENGTH(NN)
    ----------
          1005hr@ORCL> select dump(nn) from t;DUMP(NN)
    ----------------------------------------------------------------------------------------------------
    Typ=1 Len=3015: 228,184,128,228,186,140,228,186,140,228,186,140,228,186,140,228,186,140,228,186,140,
    228,186,140,228,186,140,228,186,140,228,186,140,228,186,140,228,186,140,228,186,140,228,186,140,228,
    186,140,228,186,140,228,186,140,228,186,140,228,186,140,228,186,140,228,186,140,228,186,140,228,186,
    140,228,186,140,228,186,140,228,186,140,228,186,140,228,186,140,228,186,140,228,186,140,228,186,140,
    228,186,140,228,186,140,228,186,140,228,186,140,228,186,140,228,186,140,228,186,140,228,186,140,228,
    186,140,228,186,140,228,186,140,228,186,140,228,186,140,228,186,140,228,186,140,228,186,140,228,186,
    140,228,186,140,228,186,140,228,186,140,228,186,140,228,186,140,228,186,140,228,186,140,228,186,140,
      

  4.   

    在网上找到一种解释是:在存储过程中varchar2可以传递4000个字符(2000个汉字),而在表结构中varchar2最多可以保存2000个字符(1000个汉字),所以虽然可以传递4000个字符,在保存到数据库中时,会自动截取。
        但是这种解释貌似官方文档上找不到,不知道是不是这么回事? 这种SB解释只要有脑袋的人都不信,PL/SQL中varchar2的长度是1~32767
      

  5.   

    varchar2(4000 char)
    varchar2(4000 byte)
    遇到多字节字符的时候,varchar2(4000 byte)最坏的结果只能存 1000个字符,可能每个字符站四个字节.
    varchar2(4000 char)是可以存4000个字符的
      

  6.   

    一般而言,在字符集为ZHS16GBK的是后,国家字符集只能通常是UTF8或者AL16UTF16(至少1Og是这么回事)。
    这就意味着在10g中,只要字段不是N开头的,那么存储汉字都是两个字节表示一个汉字(基本如此),所以说无法存入2000个汉字,在10g中是不可能的。
    而有时候无法存入,这只能说明工具有问题,非oracle的问题,某些工具,譬如PL/SQL DEVELOPER不同的版本有一些差异,有些对处理这里字符就会存在问题,这主要是因为这类工具很多是用OCI接口编写的,而C处理字符串如果没有弄好,就变得有问题。所以,总结下,这是工具的问题,oracle不至于会犯那么根本上的问题。
      

  7.   


    你这个例子跟我这边做结果是一样,我现在才发现,rpad填充时,n是代表字节长度,而不是字符长度!?所以n=2010时插入总共是1005个汉字
      

  8.   

    Quote: 引用 4 楼 linwaterbin 的回复:

    这和你的字符集设置有关、没有谁规定一个字符等于两个汉字吧
    二楼那只是凑巧、以下是我的测试[code=sql]sys@ORCL> select * from sys.props$ where name='NLS_CHARACTERSET';NAME                 VALUE$     COMMENT$
    -------------------- ---------- --------------------
    NLS_CHARACTERSET     AL32UTF8   Character sethr@ORCL> drop table t purge;Table dropped.hr@ORCL> create table t(nn varchar2(4000));Table created.hr@ORCL> insert into t select rpad('一',2010,'二') from dual;1 row created.hr@ORCL> select lengthb(nn) from t;LENGTHB(NN)
    -----------
           3015hr@ORCL> select length(nn) from t;LENGTH(NN)
    ----------
          1005 
    Quote:

    你这例子我又不懂了,按照我和2楼做的实验,应该是插入2010个字节才对,到了你这里怎么变成3015个字节了?
    怎么不管汉字占2字节还是3字节,n=2010都是插入1005个汉字?!
      

  9.   

    查了下官方文档,rpad对length的解释如下:
    那么5楼的实验如何解释啊?为什么最终长度超过了2010字节!
      

  10.   

    varchar2(4000) 这里是4000个字节,说明这个字段就是4000个字节咯你的数据库字符集是GBK,一个汉字点2个字节,就存2000个汉字。另外,PLSQL中(也可以理解为你说的存储过程),varchar最大是32767
      

  11.   

    补充下,我是用select for update更新,将超过1000个汉字直接copy进去时遇到这个问题的。如果用2楼的办法,insert into select 的方式,则可以插入2000个汉字。这是为什么呢?