今天有朋友数据库出现ora-29275 部分多字节字符,对应的字段只能用to_char才能正常查询,感觉是字符集问题。询问之果然修改过字符集。
他的修改方式:
sql>startup mount;
sql>alter system enable restricted session;
sql>alter system set job_queue_processes=0;
sql>alter system set aq_tm_processes=0;
sql>alter database open;
sql>alter database character set internal_use zhs16gbk;
查看数据库:
sql> select name,value$ from props$ where name like '%nls%';
name value$
------------------------------ ------------------------------
nls_language american
nls_territory america
nls_currency $
nls_iso_currency america
nls_numeric_characters .,
nls_characterset zhs16gbk
nls_calendar gregorian
nls_date_format dd-mon-rr
nls_date_language american
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 $
nls_comp binary
nls_length_semantics byte
nls_nchar_conv_excp false
nls_nchar_characterset al16utf16
nls_rdbms_version 11.2.0.1.0
确实已经修改好了。但是这里:
alter database character set internal_use zhs16gbk;
是非常有问题的,这里跳过字符集子集检查,强制进行修改。
所以以后的数据将会出现问题。
那么我们使用exp/imp在导出的时候指定字符集进行转换呢?
引入一篇文章的部分段落:
9i之前的版本:在源数据库的字符集和export的session的nls_lang设置不同时,,所有数据的字符集(用户数据和字典数据)均会转换;
在import过程中,如果import session的nls_lang和export时不一致,将会将dmp中的字符集转换成import session的nls_lang设置成的字符集;
当import session的nls_lang和目标数据库的字符集不一致时,将会发生公import session的nls_lang字符集到目标数据库的字符集转换
9i及之后的版本:在源数据库的字符集和export的session的nls_lang设置不同时,只有字典数据会发生字符集转换,用户数据则和源数据库的字符集一致,而忽略nls_lang的设置;
在import过程中,如果import session的nls_lang和export时不一致,将会将dmp中的字符集转换成import session的nls_lang设置成的字符集;
当import session的nls_lang和目标数据库的字符集不一致时,将会发生公import session的nls_lang字符集到目标数据库的字符集转换
其实都没关系,不管你用什么办法转换,只要转换的字符集不是原字符集的超集都是有问题的:
所以我们在修改数据库字符集的时候,执行如下语句:
alter database character set zhs16gbk
如果没有报:
sys@zbdba>alter database character set zhs16gbk;
alter database character set zhs16gbk
*
error at line 1:
ora-12712: new character set must be a superset of old character set
那说明可以修改。如果有以上错误,建议不要修改强制修改字符集
oracle关于字符集的分析
oracle数据库字符集研究
本文永久更新链接地址:
