0
点赞
收藏
分享

微信扫一扫

Oracle-修改字符集

oracle的字符集有互相的包容关系。如us7ascii就是zhs16gbk的子集,从us7ascii到zhs16gbk不会有数据解释上的问题,不会有数据丢失。在所有的字符集中utf8应该是最大,因为它基于unicode,双字节保存字符(也因此在存储空间上占用更多)。
一旦数据库创建后,数据库的字符集理论上讲是不能改变的。字符集的转换是从子集到超集受支持,反之不行。如果两种字符集之间根本没有子集和超集的关系,那么字符集的转换是不受oracle支持的。一般来说,除非万不得已,我们不建议修改oracle数据库server端的字符集。特别说明,我们最常用的两种字符集ZHS16GBK和ZHS16CGB231280之间不存在子集和超集关系,因此理论上讲这两种字符集之间的相互转换不受支持。

RAC-修改实例字符集

RAC环境下,修改字符集时,需要关闭全部节点。然后打开节点1,在节点1下操作即可。

SYS@b19c01> startup
ORACLE instance started.

Total System Global Area 2734682488 bytes
Fixed Size 9138552 bytes
Variable Size 553648128 bytes
Database Buffers 2164260864 bytes
Redo Buffers 7634944 bytes
Database mounted.
Database opened.
SYS@b19c01> select userenv('language') from dual;

USERENV('LANGUAGE')
----------------------------------------------------
AMERICAN_AMERICA.AL32UTF8

SYS@b19c01> show parameter cluster_database

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
cluster_database boolean TRUE
cluster_database_instances integer 2
SYS@b19c01> alter system set cluster_database=FALSE sid='*' scope=spfile;

System altered.

SYS@b19c01> show parameter cluster_database

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
cluster_database boolean TRUE
cluster_database_instances integer 2
SYS@b19c01> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SYS@b19c01>
SYS@b19c01> startup nomount
ORACLE instance started.

Total System Global Area 2734682488 bytes
Fixed Size 9138552 bytes
Variable Size 553648128 bytes
Database Buffers 2164260864 bytes
Redo Buffers 7634944 bytes
SYS@b19c01> alter database mount exclusive;

Database altered.

SYS@b19c01> alter system enable restricted session;

System altered.

SYS@b19c01> alter system set job_queue_processes=0;

System altered.

SYS@b19c01> alter system set aq_tm_processes=0;

System altered.

SYS@b19c01> alter database open;

Database altered.

SYS@b19c01> show parameter cluster_database

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
cluster_database boolean FALSE
cluster_database_instances integer 1
SYS@b19c01>
SYS@b19c01> alter database character set internal_use ZHS16GBK;

Database altered.

SYS@b19c01> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SYS@b19c01> startup
ORA-01102: cannot mount database in EXCLUSIVE mode
SYS@b19c01>
SYS@b19c01> startup
ORA-01102: cannot mount database in EXCLUSIVE mode
SYS@b19c01>
SYS@b19c01> startup
ORACLE instance started.

Total System Global Area 2734682488 bytes
Fixed Size 9138552 bytes
Variable Size 553648128 bytes
Database Buffers 2164260864 bytes
Redo Buffers 7634944 bytes
Database mounted.
Database opened.
SYS@b19c01>
SYS@b19c01> select userenv('language') from dual;

USERENV('LANGUAGE')
--------------------------------------------------------------------------------
AMERICAN_AMERICA.ZHS16GBK

SYS@b19c01> set linesize 200;
SYS@b19c01> col parameter for a30;
SYS@b19c01> col value for a40;
SYS@b19c01> select * from v$nls_parameters;

PARAMETER VALUE CON_ID
------------------------------ ---------------------------------------- ----------
NLS_LANGUAGE AMERICAN 1
NLS_TERRITORY AMERICA 1
NLS_CURRENCY $ 1
NLS_ISO_CURRENCY AMERICA 1
NLS_NUMERIC_CHARACTERS ., 1
NLS_CALENDAR GREGORIAN 1
NLS_DATE_FORMAT DD-MON-RR 1
NLS_DATE_LANGUAGE AMERICAN 1
NLS_CHARACTERSET ZHS16GBK 1
NLS_SORT BINARY 1
NLS_TIME_FORMAT HH.MI.SSXFF AM 1

PARAMETER VALUE CON_ID
------------------------------ ---------------------------------------- ----------
NLS_TIMESTAMP_FORMAT DD-MON-RR HH.MI.SSXFF AM 1
NLS_TIME_TZ_FORMAT HH.MI.SSXFF AM TZR 1
NLS_TIMESTAMP_TZ_FORMAT DD-MON-RR HH.MI.SSXFF AM TZR 1
NLS_DUAL_CURRENCY $ 1
NLS_NCHAR_CHARACTERSET AL16UTF16 1
NLS_COMP BINARY 1
NLS_LENGTH_SEMANTICS BYTE 1
NLS_NCHAR_CONV_EXCP FALSE 1

19 rows selected.

SYS@b19c01>

startup
##查询当前字符集
select userenv('language') from dual;
##设置参数cluster_database=FALSE
alter system set cluster_database=FALSE scope=spfile sid='*';
##关闭数据库
shutdown immediate
##启动数据库到nomount
startup nomount
##启动数据库到mount exclusive模式
alter database mount exclusive;
##启用受限会话
alter system enable restricted session;
##设置作业队列进程为0
alter system set job_queue_processes=0;
##设置aq_tm_processes=0 此参数监控队列消息的时间, 并控制处理具有指定延迟和过期属性的消息。
alter system set aq_tm_processes=0;
##打开数据库
alter database open;
##设置字符集 internal_use跳过子集与超集的检验修改字符集
alter database character set internal_use ZHS16GBK;
##恢复参数cluster_database=TRUE
alter system set cluster_database=TRUE sid='*' scope=spfile;
##恢复消息队列参数为默认值
alter system set job_queue_processes=1000;
alter system set aq_tm_processes=1;
##关闭
shutdown immediate
##启动
startup

####修改完成后,以下3个参数,改回原值
##在单机环境下 参数 cluster_database 不需要做修改。
##参数 cluster_database 如果为 FALSE,在集群环境下,只能启动一个节点
##否则会报错 ORA-01102: cannot mount database in EXCLUSIVE mode
alter system set cluster_database=TRUE sid='*' scope=spfile;
##以下两个参数关系到消息队列,也需修改为默认值
alter system set job_queue_processes=1000;
alter system set aq_tm_processes=1;

RAC-修改PDB字符集

SYS@b19c01> show pdbs

CON_ID CON_NAME OPEN MODE RESTRICTED
---------- ------------------------------ ---------- ----------
2 PDB$SEED READ ONLY NO
3 PDB1 READ WRITE NO
4 PDB2 MOUNTED
SYS@b19c01> alter session set container=pdb1;

Session altered.

SYS@b19c01> select userenv('language') from dual;

USERENV('LANGUAGE')
----------------------------------------------------
AMERICAN_AMERICA.AL32UTF8

SYS@b19c01> alter pluggable database pdb1 close immediate;

Pluggable database altered.

SYS@b19c01> alter pluggable database pdb1 open read write restricted;

Pluggable database altered.

SYS@b19c01> select userenv('language') from dual;

USERENV('LANGUAGE')
----------------------------------------------------
AMERICAN_AMERICA.AL32UTF8

SYS@b19c01> alter database character set internal_use ZHS16GBK;
alter database character set internal_use ZHS16GBK
*
ERROR at line 1:
ORA-65025: Pluggable database PDB1 is not closed on all instances.


SYS@b19c01> alter database character set internal_use ZHS16GBK;

Database altered.

SYS@b19c01> alter pluggable database pdb1 close immediate;

Pluggable database altered.

SYS@b19c01> alter pluggable database pdb1 open;

Pluggable database altered.

SYS@b19c01> select userenv('language') from dual;

USERENV('LANGUAGE')
--------------------------------------------------------------------------------
AMERICAN_AMERICA.ZHS16GBK

SYS@b19c01> set linesize 200;
SYS@b19c01> col parameter for a30;
SYS@b19c01> col value for a40;
SYS@b19c01> select * from v$nls_parameters;

PARAMETER VALUE CON_ID
------------------------------ ---------------------------------------- ----------
NLS_LANGUAGE AMERICAN 3
NLS_TERRITORY AMERICA 3
NLS_CURRENCY $ 3
NLS_ISO_CURRENCY AMERICA 3
NLS_NUMERIC_CHARACTERS ., 3
NLS_CALENDAR GREGORIAN 3
NLS_DATE_FORMAT DD-MON-RR 3
NLS_DATE_LANGUAGE AMERICAN 3
NLS_CHARACTERSET ZHS16GBK 3
NLS_SORT BINARY 3
NLS_TIME_FORMAT HH.MI.SSXFF AM 3

PARAMETER VALUE CON_ID
------------------------------ ---------------------------------------- ----------
NLS_TIMESTAMP_FORMAT DD-MON-RR HH.MI.SSXFF AM 3
NLS_TIME_TZ_FORMAT HH.MI.SSXFF AM TZR 3
NLS_TIMESTAMP_TZ_FORMAT DD-MON-RR HH.MI.SSXFF AM TZR 3
NLS_DUAL_CURRENCY $ 3
NLS_NCHAR_CHARACTERSET AL16UTF16 3
NLS_COMP BINARY 3
NLS_LENGTH_SEMANTICS BYTE 3
NLS_NCHAR_CONV_EXCP FALSE 3

19 rows selected.

SYS@b19c01>

alter session set container=pdb1;
alter pluggable database pdb1 close immediate;
##打开 PDB 受限状态
alter pluggable database pdb1 open read write restricted;
##修改字符集
alter database character set internal_use ZHS16GBK;
alter pluggable database pdb1 close immediate;
alter pluggable database pdb1 open;
select userenv('language') from dual;

单机-修改字符集

startup mount 
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 zhs16gbk; 
--ORA-12712: new character set must be a superset of old character set 
--ORA-12712:新字符集必须为旧字符集的超集
alter database character set internal_use zhs16gbk; 
--使用 internal_use 使oracle数据库绕过了子集与超集的校验. 
shutdown immediate
startup 

dmp-修改字符集

dmp文件的第2第3字节记录了字符集信息,因此直接修改dmp文件的第2第3字节的内容就可以'骗'过oracle的检查。这样做理论上也仅是从子集到超集可以修改,但很多情况下在没有子集和超集关系的情况下也可以修改,我们常用的一些字符集,如US7ASCII,WE8ISO8859P1,ZHS16CGB231280,ZHS16GBK基本都可以改。因为改的只是dmp文件,所以影响不大。

具体的修改方法比较多,最简单的就是直接用UltraEdit修改dmp文件的第2和第3个字节。比如想将dmp文件的字符集改为ZHS16GBK,可以用以下SQL查出该种字符集对应的16进制代码:

> select to_char(nls_charset_id('ZHS16GBK'),'xxxx') from dual;

TO_CHAR(NLS_CHA
---------------
354

然后将dmp文件的2、3字节修改为354即可。

举报

相关推荐

0 条评论