Oracle数据库的编码格式决定了字符的存储和解析规则,当编码和实际业务使用的字符集不匹配时,就会出现中文乱码、特殊字符无法存储等问题,修改编码格式是这类问题的常用解决方案。

一、查看当前Oracle数据库编码格式
在修改编码之前,需要先确认当前数据库的字符集和客户端编码配置,避免误操作。
1. 查看数据库服务端字符集
登录数据库后执行以下SQL语句即可获取服务端编码:
-- 查询数据库字符集 SELECT * FROM nls_database_parameters WHERE parameter LIKE '%CHARACTERSET%';
执行结果中NLS_CHARACTERSET是数据库字符集,NLS_NCHAR_CHARACTERSET是国家字符集,这两个是服务端编码的核心配置。
2. 查看客户端编码配置
客户端编码由环境变量NLS_LANG控制,在Linux系统下可以通过以下命令查看:
# 查看NLS_LANG环境变量 echo $NLS_LANG
Windows系统可以在系统环境变量设置中查看NLS_LANG的值,或者打开命令行执行set NLS_LANG查看。
二、Oracle数据库编码格式修改步骤
Oracle数据库编码修改需要重启数据库到特定状态执行操作,生产环境建议提前做好全库备份,避免数据丢失。
1. 单实例数据库修改步骤
以将字符集从ZHS16GBK修改为AL32UTF8为例,操作步骤如下:
- 第一步:关闭数据库
- 第二步:启动数据库到mount状态
- 第三步:修改字符集配置
- 第四步:重启数据库生效
具体执行代码:
-- 1. 关闭数据库 SHUTDOWN IMMEDIATE; -- 2. 启动到mount状态 STARTUP MOUNT; -- 3. 设置会话字符集并修改数据库字符集 ALTER SYSTEM ENABLE RESTRICTED SESSION; ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0; ALTER SYSTEM SET AQ_TM_PROCESSES=0; ALTER DATABASE OPEN; ALTER DATABASE CHARACTER SET INTERNAL_USE AL32UTF8; -- 4. 关闭并重启数据库 SHUTDOWN IMMEDIATE; STARTUP;
注意:如果修改的字符集不是原字符集的超集,需要加上INTERNAL_USE参数,否则会执行失败。
2. RAC集群环境修改步骤
RAC环境修改编码需要先关闭所有节点的数据库实例,仅在一个节点上执行修改操作,步骤如下:
-- 1. 所有节点关闭实例 srvctl stop database -d 数据库名; -- 2. 在其中一个节点启动实例到mount状态 sqlplus / as sysdba STARTUP MOUNT; -- 3. 执行修改操作(和单实例修改语句一致) ALTER SYSTEM ENABLE RESTRICTED SESSION; ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0 SCOPE=SPFILE; ALTER SYSTEM SET AQ_TM_PROCESSES=0 SCOPE=SPFILE; ALTER DATABASE OPEN; ALTER DATABASE CHARACTER SET INTERNAL_USE AL32UTF8; -- 4. 重启所有节点实例 srvctl start database -d 数据库名;
三、客户端编码适配修改
服务端编码修改完成后,还需要调整客户端NLS_LANG配置,保证客户端和服务端编码一致,避免乱码。
1. Linux系统配置
在用户环境变量文件~/.bash_profile中添加以下内容:
# 设置NLS_LANG,格式为 语言_地区.字符集 export NLS_LANG="SIMPLIFIED CHINESE_CHINA.AL32UTF8"
执行source ~/.bash_profile让配置生效。
2. Windows系统配置
打开系统环境变量设置,新建系统变量,变量名填NLS_LANG,变量值填SIMPLIFIED CHINESE_CHINA.AL32UTF8,保存后重启客户端工具即可。
四、修改注意事项
- 修改前必须做全库备份,字符集修改不可逆,操作失误可能导致数据损坏。
- 如果数据库中已经存储了大量非ASCII字符,修改字符集前需要确认新字符集支持原有字符,避免字符丢失。
- 修改完成后需要验证所有业务表的字符字段是否正常,尤其是之前存在乱码的表。
- 如果使用的是CDB容器数据库,需要分别修改CDB和PDB的字符集,PDB的修改需要在PDB打开的状态下执行对应语句。
字符集修改属于高风险操作,非必要不建议随意修改生产环境数据库的编码格式,优先通过统一客户端和服务端编码的方式解决乱码问题。