一般设计数据库的时候,我们都考虑一个汉字占用两个字节。所以设计数据库的时候,如果认为某字段最长要存四个汉字,该字段都会定义为varchar2(8)。
SQL> create table t1 (col1 varchar2(8));
Table created.
但是测试插入三个汉字的时候就报错了。
SQL> insert into t1 values('一二三');
insert into t1 values('一二三')
*
ERROR at line 1:
ORA-12899: value too large for column T1.COL1 (actual: 9, maximum:8)
检查相关参数及环境变量。
SQL> select * from nls_database_parameters where parameter like 'NLS%CHARACTERSET';
PARAMETER VALUE
------------------------- --------------------
NLS_CHARACTERSET UTF8
NLS_NCHAR_CHARACTERSET UTF8
客户端NLS_LANG=AMERICAN_AMERICA.ZHS16GBK。
原来数据库使用的是UTF8字符集,难怪一个汉字占用3个字节。这样一来原先按一个汉字占两个字节设计的数据库,应用的时候很多字段都会因长度不够,出现ORA-12899错误。
不能把数据库的字符集改成ZHS16GBK。因为系统要求不仅能支持中文,还要能支持其他亚洲字符。这样CHARACTER SET就只能设这成UTF8或AL32UTF8,这两种字符集每个汉字占用的字节数分别是3和4,都不是2。
更改所有CHAR/VARCHAR字段的长度也不现实。整套系统是从其他公司买的产品,内含上千张表,逐个去修改字段不太可能。
查看参数NLS_LENGTH_SEMANTICS。
Oracl文档中的说明:
Syntax: NLS_LENGTH_SEMANTICS = string
Range of values: BYTE | CHAR
NLS_LENGTH_SEMANTICS enables you to create CHAR and VARCHAR2 columns using either byte or character length semantics. Existing columns are not affected.
NCHAR, NVARCHAR2, CLOB, and NCLOB columns are always character-based. You may be required to use byte semantics in order to maintain compatibility with existing applications.
NLS_LENGTH_SEMANTICS does not apply to tables in SYS and SYSTEM. The data dictionary always uses byte semantics.
查看数据库中该参数的设置。
SQL> select * from nls_database_parameters where parameter like 'NLS%SEMANTICS';
PARAMETER VALUE
------------------------- --------------------
NLS_LENGTH_SEMANTICS BYTE
SQL> show parameter nls_length
NAME TYPE VALUE
------------------------------------ ---------- -------
nls_length_semantics string BYTE
把该参数改成CHAR
SQL>alter system set NLS_LENGTH_SEMANTICS=BYTE scope=BOTH;
修改后查看参数。
SQL> show parameter nls_length
NAME TYPE VALUE
------------------------------------ ---------- -------
nls_length_semantics string CHAR
从新执行insert操作。
SQL> insert into t1 values('一二三');
insert into t1 values('一二三')
*
ERROR at line 1:
ORA-12899: value too large for column T1.COL1 (actual: 9, maximum:8)
还是出错!
新创建一张表,再测试。
SQL> create table t2 (col1 varchar2(8));
表已创建。
SQL> insert into t2 values('一二三')
已创建 1 行。
SQL> select * from t2;
COL1
----------------
一二三
OK了
再查看t1和t2的表结构,可以发现一些差别。
SQL> desc t1
名称 是否为空? 类型
-------------------- -------- -------------------------
COL1 VARCHAR2(8)
SQL> desc t2
名称 是否为空? 类型
-------------------- -------- -------------------------
COL1 VARCHAR2(8 CHAR)
参数NLS_LENGTH_SEMANTICS改成CHAR以后,t2.col1列可以存储8个汉字,英文字符也只能存储8个。
SQL> insert into t2 values('一二三四五六七八');
已创建 1 行。
SQL> insert into t2 values('abcdefgh');
已创建 1 行。
SQL> insert into t2 values('abcdefghi');
insert into t2 values('abcdefghi')
*
ERROR 位于第 1 行:
ORA-12899: value too large for column T2.COL1 (actual: 9, maximum:8)
本文转自:
http://wuhuizhong.iteye.com/blog/740553
分享到:
相关推荐
8. 在完成字符集调整后,可以尝试重新导入数据,这时应该能避免`ORA-12899`错误。 需要注意的是,更改数据库字符集是一项重大操作,可能对现有的数据和应用程序产生影响。在执行这些步骤之前,一定要备份数据库,并...
出现ORA-12899,是字符集引起的,中文在UTF-8中占3个字节,ZHS16GBK中占2个字节,而源dmp文件字符集是ZHS16GBK库里倒出来的数据,现在要导入到目标字符集为UTF-8的库里,所以会出现ORA-12899 其实只要修改一下ORACLE 的...
这将确保客户端与服务器端的字符集保持一致,从而减少因字符集不匹配而引发的ORA-01460错误。 ##### Step 3: 考虑数据类型及API使用 在处理二进制流数据时,可能会调用`PreparedStatement`的`...
首先,了解"ORA-12737"错误:这是一个与字符集相关的错误,意味着客户端的环境不支持与数据库服务器通信时所需的字符集。在Oracle数据库系统中,字符集用于存储和显示文本数据,不同的字符集能够处理不同的语言和...
最后,使用`ALTER DATABASE`命令更改数据库的本地字符集为ZHS16GBK(GBK的双字节实现)和国际字符集为AL16UTF16(支持Unicode的字符集)。 2. **处理错误信息**: - 当提示`ORA-12717`时,表示数据库中存在NCLOB、...
- **国家字符集**(National Character Set):如`AL32UTF8`,主要用于存储Unicode数据。 - **内部使用字符集**(Internal Use Character Set):如`ZHS16GBK`,用于存储非Unicode数据,主要用于内部处理。 3. **...
例如,可能会使用Oracle的UTL_I18N库中的函数,如UTL_I18N.RAW_TO_CHAR,将字节流转换为字符,并利用其对多语言字符集的支持,包括UTF8。 UTF8是一种广泛使用的Unicode字符编码,它可以表示世界上几乎所有的文字。...
### Oracle11g 字符集 AL32UTF8 修改为 ZHS16GBK 的步骤与注意事项 #### 一、背景介绍 在Oracle11g环境下,可能会遇到需要更改数据库字符集的情况,例如从AL32UTF8修改为ZHS16GBK。这种变更通常发生在需要支持特定...
这里的`AMERICAN_AMERICA`表示语言和地区,而`UTF8`则表示字符集编码。 #### 四、理解NLS_LANG参数 - **NLS_LANG**:该环境变量用于定义客户端的区域设置,包括语言、地区和字符集。 - **LANGUAGE**:指定客户端...
**ORA-17037**:UTF-8 和 UCS-2 之间的转换错误,可能是因为字符集不兼容。 **ORA-17038**:字符串转换错误,可能是因为字符串格式不正确。 **ORA-17039**:字符转换错误,可能是因为字符集编码问题。 **ORA-...
- **字符集识别**:Oracle数据库支持多种字符集,如AL32UTF8、WE8ISO8859P1等,不同的字符集用于支持不同语言和特殊字符。在导入导出过程中,确保源和目标数据库的字符集兼容至关重要,否则可能导致乱码。 - **字符...
在处理Oracle数据库时,经常会遇到与字符集相关的问题,尤其是在需要更改数据库的字符集时。本文将详细介绍如何通过PL/SQL Developer或其他Oracle管理工具来查询及修改Oracle数据库的字符集。 #### 查询Oracle字符...
例如,如果当前字符集是`AL32UTF8`,则新字符集应该是能够包含所有旧字符集中的字符的字符集。 - **尝试直接更改**(通常会失败): ```sql SQL> alter database character set zhs16gbk; ERROR at line 1: ORA...
文档中提到,在安装ORACLE数据库时,默认选择了`ALU32UTF8`这一字符集。而在后续使用新中大软件进行数据同步时,由于该软件默认使用的字符集为`ZHS16GBK`,两者之间的差异导致了数据长度问题。 ##### 解决方案 为了...
2. Oracle字符集:Oracle支持多种字符集,如AL32UTF8(Unicode的UTF-8编码)、WE8ISO8859P1(西欧语言)等。数据库服务器和客户端需要保持字符集一致,以避免乱码问题。 二、客户端字符集设置 1. sqlnet.ora文件...
Oracle数据库支持多种字符集,包括单字节字符集(如ASCII)和多字节字符集(如UTF-8)。正确的字符集选择对于避免乱码、提高数据完整性以及优化性能具有重要意义。 ### 修改Oracle数据库字符集的原因及挑战 #### ...
- 单字节编码:7位字符集(如US7ASCII)和8位字符集(如WE8ISO8859P1)主要用于英语和其他欧洲语言。 - 多字节编码:分为变长和定长两种。变长多字节编码(如AL32UTF8,支持日语、汉语等)中,字符可以由1至多个字节...