一,汉字在oracle中占用字节数
一定要在建库的时候就选择好字符集,否则可能给后续的开发或者迁移带来问题。在开发中字符集问题通常会导致应用层面上的字符越界或者乱码问题。
先来看看2个使用不同字符集的数据库:
先来看server1:
SQL> select * from v$nls_parameters a ;
PARAMETER VALUE
---------------------------------------------------------------- ----------------------------------------------------------------
NLS_LANGUAGE SIMPLIFIED CHINESE
NLS_TERRITORY CHINA
NLS_CURRENCY RMB
NLS_ISO_CURRENCY CHINA
NLS_NUMERIC_CHARACTERS .,
NLS_CALENDAR GREGORIAN
NLS_DATE_FORMAT DD-MON-RR
NLS_DATE_LANGUAGE SIMPLIFIED CHINESE
NLS_CHARACTERSET WE8ISO8859P1
NLS_SORT BINARY
NLS_TIME_FORMAT HH.MI.SSXFF AM
NLS_TIMESTAMP_FORMAT DD-MON-RR HH.MI.SSXFF AM
NLS_TIME_TZ_FORMAT HH.MI.SSXFF AM TZR
NLS_TIMESTAMP_TZ_FORMAT DD-MON-RR HH.MI.SSXFF AM TZR
NLS_DUAL_CURRENCY RMB
NLS_NCHAR_CHARACTERSET AL16UTF16
NLS_COMP BINARY
NLS_LENGTH_SEMANTICS BYTE
NLS_NCHAR_CONV_EXCP FALSE
19 rows selected
SQL> select '汉字' from dual;
'??'
------
?
再看看server2:
SQL> select * from v$nls_parameters a ;
PARAMETER VALUE
---------------------------------------------------------------- ----------------------------------------------------------------
NLS_LANGUAGE SIMPLIFIED CHINESE
NLS_TERRITORY CHINA
NLS_CURRENCY RMB
NLS_ISO_CURRENCY CHINA
NLS_NUMERIC_CHARACTERS .,
NLS_CALENDAR GREGORIAN
NLS_DATE_FORMAT DD-MON-RR
NLS_DATE_LANGUAGE SIMPLIFIED CHINESE
NLS_CHARACTERSET AL32UTF8
NLS_SORT BINARY
NLS_TIME_FORMAT HH.MI.SSXFF AM
NLS_TIMESTAMP_FORMAT DD-MON-RR HH.MI.SSXFF AM
NLS_TIME_TZ_FORMAT HH.MI.SSXFF AM TZR
NLS_TIMESTAMP_TZ_FORMAT DD-MON-RR HH.MI.SSXFF AM TZR
NLS_DUAL_CURRENCY RMB
NLS_NCHAR_CHARACTERSET AL16UTF16
NLS_COMP BINARY
NLS_LENGTH_SEMANTICS BYTE
NLS_NCHAR_CONV_EXCP FALSE
19 rows selected
SQL> select '汉字' from dual;
'汉字'
------
汉字
通过比较上述两个数据库的区别,发现他们的NLS_CHARACTERSET不同,一个是WE8ISO8859P1,而另外一个是AL32UTF8。WE8ISO8859P1是单字节8位字符集,AL32UTF8是变长多字节编码。
现在的客户端的字符集为:SIMPLIFIED CHINESE_CHINA.ZHS16GBK
WE8ISO8859P1没有汉字编码,一般来讲,有中文字符就不应该使用这个字符集,虽然修改客户端和服务器端相同时可以解决乱码问题。
有关汉字在oracle中占用的字节数问题:
在WE8ISO8859P1字符集下,一个汉字占了1个字节。
在AL32UTF8字符集下面,一个汉字占了3个字节。
在ZHS16GBK是占用了2个字节。
Varchar2,varchar,nvarchar2均为变长字符类型,char则是固定长度。
用vsize函数来看的话很明显:
Server1:
SQL> select vsize('汉') from dual;
VSIZE('?')
-----------
1
Server2:
SQL> select vsize('汉') from dual;
VSIZE('汉')
-----------
3
而用length来看,则均为1:
Server1:
SQL> select length('汉') from dual;
LENGTH('?')
------------
1
Server2:
SQL> select length('汉') from dual;
LENGTH('汉')
------------
1
下面具体来看个对比:
Server1和server2中均建立下面的表:
create table t_test_var
(
v_char2 char(2),
v_char3 char(3),
v_varchar22 varchar2(2),
v_varchar23 varchar2(3),
v_varchar2 varchar(2),
v_varchar3 varchar(3),
v_nvarchar22 nvarchar2(2),
v_nvarchar23 nvarchar2(3)
);
然后分别在两个数据库中插入测试数据:
Server1:
SQL> insert into t_test_var values ('我','我','我','我','我','我','我','我');
1 row inserted
SQL> insert into t_test_var values ('我们','我们','我们','我们','我们','我们','我们','我们');
1 row inserted
SQL> insert into t_test_var values ('我们是','我们是','我们是','我们是','我们是','我们是','我们是','我们是');
insert into t_test_var values ('我们是','我们是','我们是','我们是','我们是','我们是','我们是','我们是')
ORA-12899: value too large for column "TEST"."T_TEST_VAR"."V_CHAR2" (actual: 3, maximum: 2)
说明server1中char用一个字节来存储一个汉字。
修改一下最后一条插入语句,使得char类型不越界:
SQL> insert into t_test_var values ('我们','我们是','我们是','我们是','我们是','我们是','我们是','我们是');
insert into t_test_var values ('我们','我们是','我们是','我们是','我们是','我们是','我们是','我们是')
ORA-12899: value too large for column "TEST"."T_TEST_VAR"."V_VARCHAR22" (actual: 3, maximum: 2)
SQL>
则说明了server1中的varchar2类型也是一个字节存储一个汉字,再次修改:
SQL> insert into t_test_var values ('我们','我们是','我们','我们是','我们是','我们是','我们是','我们是');
insert into t_test_var values ('我们','我们是','我们','我们是','我们是','我们是','我们是','我们是')
ORA-12899: value too large for column "TEST"."T_TEST_VAR"."V_VARCHAR2" (actual: 3, maximum: 2)
则说明varchar也是一个汉字占一个字节存储空间,继续修改:
SQL> insert into t_test_var values ('我们','我们是','我们','我们是','我们','我们是','我们是','我们是');
insert into t_test_var values ('我们','我们是','我们','我们是','我们','我们是','我们是','我们是')
ORA-12899: value too large for column "TEST"."T_TEST_VAR"."V_NVARCHAR22" (actual: 3, maximum: 2)
则说明nvarchar2也是一个汉字占一个字节存储空间。
这是因为在WE8ISO8859P1字符中,根本没有汉字编码。所以得出以上的实验结果。
再来看看Server2:
SQL> insert into t_test_var values ('我','我','我','我','我','我','我','我');
insert into t_test_var values ('我','我','我','我','我','我','我','我')
ORA-01401: inserted value too large for column
SQL> insert into t_test_var values ('我们','我们','我们','我们','我们','我们','我们','我们');
insert into t_test_var values ('我们','我们','我们','我们','我们','我们','我们','我们')
ORA-01401: inserted value too large for column
SQL> insert into t_test_var values ('我们是','我们是','我们是','我们是','我们是','我们是','我们是','我们是');
insert into t_test_var values ('我们是','我们是','我们是','我们是','我们是','我们是','我们是','我们是')
ORA-01401: inserted value too large for column
SQL> select cast('汉' as char(1)) from dual;
select cast('汉' as char(1)) from dual
ORA-25137: Data value out of range
SQL> select cast('汉' as char(2)) from dual;
select cast('汉' as char(2)) from dual
ORA-25137: Data value out of range
SQL> select cast('汉' as char(3)) from dual;
CAST('汉'ASCHAR(3))
-------------------
汉
SQL> insert into t_test_var (v_varchar22) values ('汉');
insert into t_test_var (v_varchar22) values ('汉')
ORA-01401: inserted value too large for column
SQL> insert into t_test_var (v_varchar23) values ('汉');
1 row inserted
oracle 不同的编码,汉字占用的字节数步同,如下
sql: select * from nls_database_parameters;
当NLS_CHARACTERSET=AL32UTF8时()
NLS_LENGTH_SEMANTICS=BYTE时,一个汉字代表三个字节
NLS_LENGTH_SEMANTICS=CHAR时,一个汉字代表一个字节
当NLS_CHARACTERSET=US7ASCII时(字符集为单字节)
NLS_LENGTH_SEMANTICS=BYTE时,一个汉字代表两个字节
NLS_LENGTH_SEMANTICS=CHAR时,一个汉字代表两个字节
NLS_LENGTH_SEMANTICS=BYTE时
在WE8ISO8859P1字符集下,一个汉字占了1个字节。
在ZHS16GBK是占用了2个字节。
分享到:
相关推荐
Oracle字符集是数据库管理系统Oracle中的一个重要概念,它决定了数据库如何存储和处理文本数据。字符集不仅影响着数据的准确性和一致性,还与全球化应用、数据迁移和数据交换密切相关。本篇将深入探讨Oracle字符集的...
### Oracle字符集修改命令详解 #### 一、引言 在Oracle数据库的管理与维护过程中,字符集的正确设置对于确保数据的正确显示与处理至关重要。由于不同的地区和语言环境对于字符编码的需求各异,因此有时可能需要...
Oracle字符集专题是一个深入探讨Oracle数据库字符集配置、管理和常见问题解决的综合资源。这个专题涵盖了从基础概念到实际操作的多个方面,旨在帮助用户全面理解并有效处理与Oracle字符集相关的各种问题。 首先,...
本文将深入探讨Oracle字符集的相关概念,包括如何通过设置环境变量来修改客户端字符集,以此解决因字符集差异而导致的数据转换或损耗问题。 #### Oracle字符集的重要性 Oracle数据库通过字符集支持多种语言环境下...
### Oracle字符集的查看与客户端字符集的修改 #### 一、Oracle字符集的基本概念 在Oracle数据库系统中,字符集(charset)是用于表示文本数据的编码方式。正确设置和管理字符集对于确保数据的一致性和正确性至关重要...
总之,Oracle字符集的正确选择和管理对于数据库的正常运行至关重要。通过快速修改注册表,我们可以便捷地在不同字符集之间切换,满足与不同数据库的兼容性需求。在日常工作中,理解并掌握字符集的相关知识,能有效...
### JDBC 连接 Oracle 字符集不同导致乱码问题解析及解决方案 #### 问题背景 在使用 JDBC(Java Database Connectivity)连接 Oracle 数据库时,可能会遇到一个常见的问题:从远程 Oracle 数据库获取的数据出现乱码...
#### 一、理解Oracle字符集 1. **字符集定义**:字符集(Character Set)是一组符号及编码规则的集合,用于存储和处理文本数据。 2. **Oracle中的字符集类型**: - **国家字符集**(National Character Set):如`...
### Oracle字符集的查看与修改详解 #### 一、Oracle字符集概述 Oracle数据库系统支持多种字符集,以便处理各种语言和地区的信息。字符集的选择对于数据的存储和处理至关重要,尤其是在全球化环境中,需要处理多种...
更改oracle 字符集,
### 知识点详解:“熟知Oracle字符集” #### 引言 Oracle的多语言支持功能,尤其是字符集的管理,是确保数据正确显示和存储的关键因素。字符集问题常常成为数据库管理和应用程序开发中的一个难点,尤其是在涉及...
Oracle字符集是数据库管理系统Oracle中用于存储和处理文本数据的关键组件。它定义了数据库能够识别和存储的不同字符的集合,包括字母、数字、符号以及特殊字符。深入理解Oracle字符集对于数据库管理员、开发人员和...
Oracle字符集是数据库管理系统Oracle中处理字符数据的关键组成部分,它定义了如何存储和显示各种语言的字符。Oracle字符集问题通常出现在数据库创建、数据输入、数据传输或在不同字符集的系统之间交互时。理解Oracle...
本文将深入探讨Oracle字符集的原理、查询方法以及如何处理字符集不一致的问题。 首先,Oracle字符集是一个定义了字节数据解释方式的集合,它具有不同的大小和包容性。Oracle支持多种国家语言,允许用户以本地化的...
Oracle字符集是数据库系统中用于表示文本数据的一种编码方式,它是Oracle数据库为了支持多种语言和文化环境而设计的重要特性。Oracle字符集不仅包含了常见的ASCII字符,还包含了各种国家和地区的特殊字符,使得用户...
Oracle 字符集查看与修改 Oracle 字符集是一个字节数据的解释的符号集合,具有大小之分,具有相互的包容关系。Oracle 支持国家语言的体系结构允许使用本地化语言来存储、处理、检索数据。 一、什么是 Oracle 字符...