`
houday123
  • 浏览: 217471 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

关于Oracle一个汉字代表几个字节的问题(转)

阅读更多
ps:本人破解了润乾报表,全部功能可用,低价销售,需要要的请加qq:229501642联系

在Oracle定义变量时,常有VARCHAR2 (3 Char)或者VARCHAR2 (10 Byte)的数据类型,那么3char或者10Byte到底代表几个汉字,几个字符呢,上次外公司一同事讨论这个问题,一下没给解释清楚,所以下来以后整理如下:

总结:
当NLS_CHARACTERSET=AL32UTF8时()
NLS_LENGTH_SEMANTICS=BYTE时,一个汉字代表三个字节
NLS_LENGTH_SEMANTICS=CHAR时,一个汉字代表一个字节
当NLS_CHARACTERSET=US7ASCII时(字符集为单字节)
NLS_LENGTH_SEMANTICS=BYTE时,一个汉字代表两个字节
NLS_LENGTH_SEMANTICS=CHAR时,一个汉字代表两个字节

现象:
select * from nls_database_parameters;
….      …………..
NLS_CHARACTERSET        AL32UTF8

…..

NLS_LENGTH_SEMANTICS BYTE

….

NLS_NCHAR_CHARACTERSET      AL16UTF16

NLS_RDBMS_VERSION      10.2.0.4.0


SQL> alter session set nls_length_semantics='BYTE';

SQL> create table nls_byte(c1 varchar2(7));

SQL> insert into nls_byte values('测试机');

insert into nls_byte values('测试机')

ORA-12899: 列 "SYS"."NLS_BYTE"."C1" 的值太大 (实际值: 9, 最大值: 7)

SQL> insert into nls_byte values('测试a');

1 row inserted

SQL> select table_name,column_name,t.DATA_TYPE,t.DATA_LENGTH,t.CHAR_USED from user_tab_columns t where table_name='NLS_BYTE';

TABLE_NAME COLU DATA_TYP DATA_LENGTH CHAR_USED

---------- ---- -------- ----------- ---------

NLS_BYTE   C1   VARCHAR2           7 B
  
NLS_LENGTH_SEMANTICS allows you to specify the length of a column datatype in terms of CHARacters rather than in terms of BYTEs. Typically this is when using an AL32UTF8 or other varying width NLS_CHARACTERSET database where one character is not always one byte. While using CHAR semantics has as such no added value in a 7/8 bit characterset it's fully supported so any application code / table setup using CHAR can also be used in a 7/8bit characterset like US7ASCII/WE8MSWIN1252.
This parameter is a 9i (and up) feature and is not available in older releases

翻译过来就是:这个参数允许将列的数据单位设为字符而不是byte.这个问题会在字符集设为UTF8的时候出现. 此参数在9i以上版本有效.

NLS_LENGTH_SEMANTICS 设置.

1.      NLS_DATABASE_PARAMETERS中的值是在数据库创建的时候确定的,一般都为BYTE

2.     此参数可以以 “ALTER SYSTEM SET NLS_LENGTH_SEMANTICS=CHAR scope=both”方式修改,但是需要重启数据库才能生效.

3.     也可用” ALTER SESSION SET NLS_LENGTH_SEMANTICS=CHAR”使对当前session生效.

4.     此参数可以在10G以上版本中,在环境变量或注册表中设置(注意需要大写),设定后从当前客户端启动的所有会话都采用新的取值.

5.     修改后只对新建的列生效,对于已有的列没有作用

6.     新建或升级DB时用BYTE,否则XDB或dba_tables会出现问题.

7.     NLS_LENGTH_SEMANTICS对sys用户下的对象无效.

8.     如果对于7/8bit的字符集,设为byte/char意义不大,因为无论是char和byte都对应一个byte.

测试:

一.在当前session中修改此参数

SQL> alter session set nls_length_semantics='char';

Session altered

SQL> create table nls_char(c1 varchar2(7),c2 varchar2(7));

Table created

SQL> desc nls_char

Name Type        Nullable Default Comments

---- ----------- -------- ------- --------

C1   VARCHAR2(7) Y                      

C2   VARCHAR2(7) Y                      

SQL> insert into nls_char values('测试机','测试测试测试');

1 row inserted 

如果对于alter system,效果是一样的

二.对于已经存在的表,

SQL> desc nls_byte

Name Type             Nullable Default Comments

---- ---------------- -------- ------- --------

C1   VARCHAR2(7 BYTE) Y                      

SQL> alter table nls_byte modify c1 varchar2(7 char);

Table altered

SQL> desc nls_byte

Name Type        Nullable Default Comments

---- ----------- -------- ------- --------

C1   VARCHAR2(7) Y                      

SQL> insert into nls_byte values('测试机');

1 row inserted

1.      exp/imp : 不能直接导入,因为会采用source table的建表方式在target db里建表,即使目标库设的值为char.

*可以预先在目标库中以char方式建表

*然后导入,指定参数ignore=y

  2. Alter table

     alter table "<owner>"."<table>" modify "<column>" char (10 char);

      创建脚本,修改列设定.

注:

Bug-3611750, ora-01450 online rebuild of index fails, 可以在重建索引前指定byte, 10.2.0.5以上已经修复

Bug 1488174 UNICODE: ALTER SYSTEM SET NLS_LENGTH_SEMANTICS DOESN'T
TAKE EFFECT, 用此语句修改后,实际上不起作用,需要重启才能生效, 但是如果用alter session方式即时生效,不用重启.

进一步测试,在另一个字符集设为us7ascii的DB设置此参数

SQL> select * from nls_database_parameters

6          NLS_CHARACTERSET  US7ASCII

SQL> alter session set nls_length_semantics=byte;

Session altered.

SQL> create table nls_byte(c1 varchar2(7));

Table created.

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

insert into  nls_byte values('测试测试')

ERROR at line 1:

ORA-12899: value too large for column "TEA"."NLS_BYTE"."C1" (actual: 8,

maximum: 7)

SQL> desc nls_byte

Name                        Null?    Type

-------------------------------

C1                                   VARCHAR2(7)

SQL> alter session set nls_length_semantics=char;

Session altered.

SQL> create table nls_char(c1 varchar2(7));

Table created.

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

insert into  nls_char values('测试测试')

ERROR at line 1:

ORA-12899: value too large for column "TEA"."NLS_CHAR"."C1" (actual: 8,

maximum: 7)

SQL> desc nls_char

Name                        Null?    Type

----------------------------------------- -------- -------------------

C1                                  VARCHAR2(7)
 
可以看出,在字符集为单字节的情况下,无论取何值,汉字都是以二个字节的方式存在的.

分享到:
评论

相关推荐

    ORACLE数据库汉字占几个字节问题.pdf

    "ORACLE数据库汉字占几个字节问题" 在 ORACLE 数据库中,汉字占用的字节数是一个常见的问题。根据数据库的字符集编码,一个汉字可以占用不同的字节数。在 AL32UTF8 或 UTF8 编码下,一个汉字通常占用 3 到 4 个字节...

    Oracle中如何用SQL检测字段是否包括中文字符

    有一个同事的数据迁移程序有个问题,没有考虑中文编码字符,由于迁移的表有几千万数据,但是有中文的记录集很少,问我能否找出有中文内容的记录数。首先我想到的是采用检测每个字节ASCII的方式,这样的话需要写一个...

    如何处理错误ORA-29275:部分多字节字符

    在Oracle数据库操作过程中,用户可能会遇到一个特定的错误提示——ORA-29275:部分多字节字符。这一错误通常出现在执行查询`SELECT * FROM V$SESSION`时。该错误的出现意味着在查询结果中存在一些多字节字符(通常是...

    几个常用的Oracle函数及实例运用

    本文将详细介绍几个常用Oracle函数及其在实际项目中的应用案例。 #### 二、常用Oracle函数详解 ##### 1. NVL 函数 NVL 函数用于替换NULL值,当第一个参数为NULL时,返回第二个参数的值;否则返回第一个参数的值。 ...

    Oracle Tuxedo.pdf

    - **FLD_MBSTRING**:这是Oracle Tuxedo提供的一个字段类型,专门用于处理多字节数据。它可以确保数据在不同编码环境之间的正确传输。 #### 结论 Oracle Tuxedo通过其丰富的多字节字符支持功能,为亚太地区的企业...

    oracle 中几种字符类型

    在 Oracle 中,CHAR 类型区分中英文,中文占两个字节,而英文占一个字节。因此,CHAR(20) 可以存储 20 个英文字符或 10 个中文字符。CHAR 类型适用于长度比较固定的,一般不含中文的情况。 二、VARCHAR 类型 ...

    Oracle接收长度大于4000的字符串

    创建一个OracleCommand对象,并通过参数化方式将Byte[]数组作为参数传递给存储过程。 ```csharp OracleCommand cmd = new OracleCommand(); cmd.Parameters.Add(new OracleParameter("xxxx", bt)); ``` #### 2. ...

    oracle数据库迁移

    Oracle 数据库迁移 Oracle 数据库迁移是指将 Oracle 数据库从一个平台迁移到另一...Oracle 数据库迁移是一个复杂的过程,需要注意字符集的设置、用户的导出和导入、表空间的创建和管理、用户的创建和管理等几个方面。

    Oracle数据库rowid深入探析.pdf

    Oracle数据库rowid是Oracle数据库中一个重要的概念,也是Oracle DBA考试中一个重要的知识点。rowid是Oracle数据库中的一种伪列,它可以唯一地标识表中的每一行。伪列类似于数据表的列,建立表时,数据库会自动为每个...

    Oracle字符集研究.pptx

    ZHS16GBK是针对简体中文的一个例子,它使用GBK编码,每个字符通常由两个字节表示。 定长多字节编码,如AF16UTF16,每一个字符都占用固定数量的字节,通常是两个字节,这对于Unicode编码特别有用。Unicode是一个全球...

    Oracle数据库字符集问题总结

    DMP文件的字符集信息存储在文件的前几个字节中,可以通过十六进制编辑器查看并转换为对应的字符集名称。客户端的字符集在Windows环境下是注册表中的NLS_LANG,在Unix环境下则是环境变量NLS_LANG。 在确保所有环境的...

    oracle字符集的查看和client字符集的修改

    - **国际化支持**:不同地区的用户可以使用各自的语言访问同一个数据库,提高用户体验。 - **兼容性**:在跨平台和跨系统的环境中,统一字符集有助于解决由于编码差异导致的问题。 #### 六、常见问题及解决方案 1....

    oracle日常函数文档

    根据提供的文档内容,本文将详细解析Oracle中几个常用的字符串处理函数及其应用场景,这些函数包括CONCAT、INITCAP、INSTR、LENGTH、LOWER、UPPER以及LPAD等。 ### 1. CONCAT - 字符串连接 #### 函数简介 `CONCAT`...

    sqlserver-oracle 数据类型对照

    - `NEXT_DAY`在Oracle中找到日期后的一个特定星期几,SQL Server无直接对应。 - `TO_CHAR`和`CONVERT`用于日期到字符串的转换。 - `TO_DATE`和`CONVERT`用于字符串到日期的转换。 - `DATEPART`和`EXTRACT`在...

    理解Oracle数据库字符集

    Oracle的字符集命名通常由三部分组成:语言、比特位数和编码方式,例如ZHS16GBK代表简体中文的GBK编码。 2. **字符编码方案**: - **单字节编码**:分为7位和8位两种,7位最多表示128个字符,8位可以表示256个字符...

    Oracle SQL 内置函数大全(3)

    下面将详细解释提供的几个关键函数: 1. **CONVERT(c, dset, sset)**:此函数用于将源字符串`sset`从一个特定的语言字符集(如`we8hp`)转换到另一个目标字符集(如`f7dec`)。这在处理多种字符集的数据时非常有用...

    行运Oracle论坛2002_xybbs2002oracle(毕设 + 课设).zip

    【描述】中的"[论坛社区]行运Oracle论坛2002_xybbs2002oracle”暗示了这些内容来源于一个早期的在线交流平台,可能是用户在论坛上分享的关于Oracle数据库的学习资源和实践经验。"毕设 + 课设"表示这些资料特别针对...

    oracle数据库ORA-29275.txt

    ZHS16CGB231280是一种用于简体中文的字符集编码,而ZHS16GBK也是一种简体中文字符集,两者之间的转换可能会导致数据损坏或其他兼容性问题。 6. **再次关闭并重启数据库**: - 再次执行`SHUTDOWN IMMEDIATE;`和`...

    Oracle函数.txt

    - **功能**:返回一个代表输入字符串发音的四位数字编码。 - **示例**: ```sql ORDER BY SOUNDEX(ename); ``` 按照名字的发音进行排序,这在处理拼写相似但拼写不同的名字时非常有用。 ### 二、NULL值处理函数...

Global site tag (gtag.js) - Google Analytics