解决Oracle乱码问题

此博文适用

  • centos7操作系统,centos6不完全适用,但是思路是一样的
  • Oracle19c,其余版本不清楚
  • 将乱码改为中文或者英文

乱码的原因操作系统的字符集与Oracle的字符集不一致

可能需要修改的地方

1.修改oracle内置的字符集

2.修改/etc/locale.conf

3.修改 ~/.bash_profile

查看字符集信息

在修改之前,先查看这些地方的字符集,根据这些查到的信息查表匹配得到合适的字符集,最终得到正常能看懂的文字。

1.在oracle中使用如下命令查看数据库内置字符集

sqlplus / as sysdba #进入数据库
select userenv('language') from dual; # 查看数据库内置字符集

2.在用户登录中使用如下命令查看

cat ~/.bash_profile # 命令查看文件内容

3.查看系统字符集文件

cat /etc/locale.conf
# 或者
echo $LANG
修改字符集

下表是locale ID与字符集名称的对应关系,修改字符集时需要查表,找到对应的信息进行修改

LanguageLocale IDNLS_LANG
English (American)en_US.UTF-8AMERICAN_AMERICA.AL32UTF8
English (American)en_US.ISO-8859-1AMERICAN_AMERICA.WE8ISO8859P1
English (American)en_US.ISO-8859-15AMERICAN_AMERICA.WE8ISO8859P15
English (Australian)en_AU.UTF-8ENGLISH_AUSTRALIA.AL32UTF8
English (Australian)en_AU.ISO-8859-1ENGLISH_AUSTRALIA.WE8ISO8859P1
English (Australian)en_AU.ISO-8859-15ENGLISH_AUSTRALIA.WE8ISO8859P15
English (British)en_GB.UTF-8ENGLISH_UNITED KINGDOM.AL32UTF8
English (British)en_GB.ISO-8859-1ENGLISH_UNITED KINGDOM.WE8ISO8859P1
English (British)en_GB.ISO-8859-15ENGLISH_UNITEDKINGDOM.WE8ISO8859P15
English (Ireland)en_IE.UTF-8ENGLISH_IRELAND.AL32UTF8
English (Ireland)en_IE.ISO-8859-1ENGLISH_IRELAND.WE8ISO8859P1
English (Ireland)en_IE.ISO-8859-15ENGLISH_IRELAND.WE8ISO8859P15
Germande_DE.UTF-8GERMAN_GERMANY.AL32UTF8
Germande_DE.ISO-8859-1GERMAN_GERMANY.WE8ISO8859P1
Germande_DE.ISO-8859-15GERMAN_GERMANY.WE8ISO8859P15
Frenchfr_FR.UTF-8FRENCH_FRANCE.AL32UTF8
Frenchfr_FR.ISO-8859-1FRENCH_FRANCE.WE8ISO8859P1
Frenchfr_FR.ISO-8859-15FRENCH_FRANCE.WE8ISO8859P15
Italianit_IT.UTF-8ITALIAN_ITALY.AL32UTF8
Italianit_IT.ISO-8859-1ITALIAN_ITALY.WE8ISO8859P1
Italianit_IT.ISO-8859-15ITALIAN_ITALY.WE8ISO8859P15
Spanishes_ES.UTF-8SPANISH_SPAIN.AL32UTF8
Spanishes_ES.ISO-8859-1SPANISH_SPAIN.WE8ISO8859P1
Spanishes_ES.ISO-8859-15SPANISH_SPAIN.WE8ISO8859P15
Spanish (Mexico)es_MX.UTF-8MEXICAN SPANISH_MEXICO.AL32UTF8
Spanish (Mexico)es_MX.ISO-8859-1MEXICAN SPANISH_MEXICO.WE8ISO8859P1
Spanish (Mexico)es_MX.ISO-8859-15MEXICANSPANISH_MEXICO.WE8ISO8859P15
Portuguese (Brazilian)pt_BR.UTF-8BRAZILIANPORTUGUESE_BRAZIL.AL32UTF8
Portuguese (Brazilian)pt_BR.ISO-8859-1BRAZILIANPORTUGUESE_BRAZIL.WE8ISO8859P1
Portuguese (Brazilian)pt_BR.ISO-8859-15BRAZILIANPORTUGUESE_BRAZIL.WE8ISO8859P15
Japaneseja_JP.EUC-JPJAPANESE_JAPAN.JA16EUC
Japaneseja_JP.UTF-8JAPANESE_JAPAN.AL32UTF8
Koreanko_KR.EUC-KRKOREAN_KOREA.KO16KSC5601
Koreanko_KR.UTF-8KOREAN_KOREA.AL32UTF8
Chinese (simplified)zh_CN.GB18030SIMPLIFIEDCHINESE_CHINA.ZHS32GB18030
Chinese (simplified)zh_CN.UTF-8SIMPLIFIED CHINESE_CHINA.AL32UTF8
Chinese (traditional)zh_TW.BIG5TRADITIONALCHINESE_TAIWAN.ZHT16BIG5
Chinese (traditional)zh_TW.UTF-8TRADITIONAL CHINESE_TAIWAN

1.修改oracle内置的字符集

# 修改方法(以改成UTF8为例)

# 以系统DBA权限登录sqlplus

sqlplus / as sysdba;

select userenv('language') from dual;

# 例如:AMERICAN_AMERICA.WE8MSWIN1252

# 修改:

SQL> shutdown immediate;

SQL> startup mount;

SQL> alter system enable restricted session;

SQL> alter system set job_queue_processes=0;

SQL> alter database open;

SQL> alter database character set internal_use AL32UTF8
# 或者  ALTER DATABASE character set INTERNAL_USE [其他字符集];

SQL> shutdown immediate;

SQL> startup

SQL>alter system disable restricted session;

2.修改/etc/locale.conf

sudo vi /etc/locale.conf
# 文件内容如下
LANG="en_US.UTF-8"

3.修改 ~/.bash_profile

vi ~/.bash_profile # 命令查看文件内容
# 此处以改为英文为例,在.bash_profile文件 所有export之后末尾添加如下一行命令
export NLS_LANG=AMERICAN_AMERICA.AL32UTF8
关于Oracle的一些结论,知其然也要知其所以然

1.对Oracle数据库存取起作用的是这些:客户端操作系统字符集、客户端操作系统参数NLS_LANG、服务端数据库字符集。

2.对Oracle数据库不起作用的是服务端操作系统字符集。

3.客户端操作系统只有一张编码表,与客户端字符集对应。

4.Oracle数据库的字符集只有一个,并且固定,一般不改变。

5.存放在Oracle数据库中的字符串的编码格式只有一个,它就是数据库的字符集所对应的编码格式。

6.Oracle数据库有很多张编码表,可以在数据存入时将其它编码格式的编码转换为数据库字符集指定的格式,取出时从数据库字符集指定的格式转换为其它编码格式

7.整个架构中的转码只发生在Oracle数据库边界上,其它地方没有。

8.Oracle是根据客户端操作系统的参数NLS_LANG与自己的字符集进行对照来确定是否需要进行转码的。

最最重要的结论出来了:

9.Oracle数据库如何选择字符集?只有一个原则,那就是这个字符集要包含数据库运行过程中所能存入的数据字符,通常作为中国人我们选择ZHS16GBK,如果想再保险一点,选择AL32UTF8。

10.服务器操作系统选择什么字符集?这个字符集与数据库字符集一点关系都没有,只跟谁有关?操作系统管理员!所以它的选择原则是,系统管理员想选择什么就选择什么。

11.客户端操作系统选择什么字符集?我是中国人,我用中文操作系统,所以我选择ZHS16GBK。建议中国人都选择ZHS16GBK。

12.客户端操作系统参数NLS_LANG参数如何设置?这个只有一个设置方法,那就是与操作系统字符集相同。要不然会出问题的……

最最最最重要的一句话:

最好的,最不容易出字符集错误的就是:将数据库字符集、客户端字符集、客户端操作系统NLS_LANG参数三个地方作同样的设置。

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐