`
houday123
  • 浏览: 214877 次
  • 性别: 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数据库汉字占几个字节问题.pdf

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

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

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

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

    Oracle9i的init.ora参数中文说明

    Oracle9i初始化参数中文说明 Blank_trimming: 说明: 如果值为TRUE, 即使源长度比目标长度 (SQL92 兼容) 更长, 也允许分配数据。 值范围: TRUE | FALSE 默认值: FALSE serializable: 说明: 确定查询是否获取表级...

    最全的oracle常用命令大全.txt

     dictionary 全部数据字典表的名称和解释,它有一个同义词dict dict_column 全部数据字典表里字段名称和解释 如果我们想查询跟索引有关的数据字典时,可以用下面这条SQL语句: SQL&gt;select * from dictionary ...

    oracle学习文档 笔记 全面 深刻 详细 通俗易懂 doc word格式 清晰 连接字符串

    2. oracle11G自带一个卸载批处理\app\Administrator\product\11.2.0\dbhome_1\deinstall\deinstall.bat 3. 运行该批处理程序将自动完成oracle卸载工作,最后手动删除\app文件夹(可能需要重启才能删除) 4. 运行...

    ORACLE中的数据类型.doc

    当你在oracle 中定义一个character 数据时,通常需要制定字段的长度,它是该字段的最大长度。ORACLE提供以下几种character 数据类型: CHAR() CHAR数据类型是一种有固定长度和最大长度的字符串。存储在数据类型为...

    Oracle截取字符串去掉字段末尾指定长度的字符

    lengthb(string)计算string所占的字节长度:返回字符串的长度,单位是字节 ...【备注】一个汉字在Oracle数据库里占多少字节跟数据库的字符集有关,UTF8时,长度为三 PS:oracle去掉字符串中所有指定字符 Selec

    java 面试题 总结

    对于客户机,EntityBean是一种持久性对象,它代表一个存储在持久性存储器中的实体的对象视图,或是一个由现有企业应用程序实现的实体。 Session Bean 还可以再细分为 Stateful Session Bean 与 Stateless Session ...

    orcale常用命令

     dictionary 全部数据字典表的名称和解释,它有一个同义词dict dict_column 全部数据字典表里字段名称和解释 如果我们想查询跟索引有关的数据字典时,可以用下面这条SQL语句: SQL&gt;select * from dictionary ...

    超级有影响力霸气的Java面试题大全文档

     对于客户机,EntityBean是一种持久性对象,它代表一个存储在持久性存储器中的实体的对象视图,或是一个由现有企业应用程序实现的实体。  Session Bean 还可以再细分为 Stateful Session Bean 与 Stateless ...

    JAVA上百实例源码以及开源项目

    5个目标文件,演示Address EJB的实现,创建一个EJB测试客户端,得到名字上下文,查询jndi名,通过强制转型得到Home接口,getInitialContext()函数返回一个经过初始化的上下文,用client的getHome()函数调用Home接口...

    JAVA上百实例源码以及开源项目源代码

    5个目标文件,演示Address EJB的实现,创建一个EJB测试客户端,得到名字上下文,查询jndi名,通过强制转型得到Home接口,getInitialContext()函数返回一个经过初始化的上下文,用client的getHome()函数调用Home接口...

    java面试宝典

    28、char 型变量中能不能存贮一个中文汉字?为什么? 10 29、abstract class 和interface 有什么区别? 10 30、Static Nested Class 和Inner Class 的不同? 11 31、java 中会存在内存泄漏吗,请简单描述。 11 32、...

    最新Java面试宝典pdf版

    3、编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串,但要保证汉字不被截取半个,如“我ABC”,4,应该截取“我AB”,输入“我ABC汉DEF”,6,应该输出“我ABC”,而不是“我ABC+汉...

    千方百计笔试题大全

    28、char 型变量中能不能存贮一个中文汉字?为什么? 10 29、abstract class 和interface 有什么区别? 10 30、Static Nested Class 和Inner Class 的不同? 11 31、java 中会存在内存泄漏吗,请简单描述。 11 32、...

    java开源包1

    目前它包含一个完整的虚拟机以及一个 javap 字节码反汇编器。 brap(Java远程调用框架 BRAP) 一个Java远程调用框架,它将原生Java对象序列化压缩装入HTTP中。它是 Spring HttpInvoker的一个轻量级选择,特别适合于当...

    java开源包11

    目前它包含一个完整的虚拟机以及一个 javap 字节码反汇编器。 brap(Java远程调用框架 BRAP) 一个Java远程调用框架,它将原生Java对象序列化压缩装入HTTP中。它是 Spring HttpInvoker的一个轻量级选择,特别适合于当...

Global site tag (gtag.js) - Google Analytics