oracle10g修改字符集

ORA-00933: SQL command not properly ended   修改字符集

http://www.itpub.net/thread-151650-1-1.html

http://topic.csdn.net/t/20020311/23/569408.html

没有不可以改的: 
update   props$   set   value$= 'ZHS16CGB231280 '   
where   name= 'NLS_CHARACTERSET '; 
update   props$   set   value$= 'ZHS16CGB231280 '   
where     name= 'NLS_NCHAR_CHARACTERSET ';

果然是可以的,看来我从Oracle7学到的知识要全面刷新。。。 

几点注意事项: 
1、执行ALTER   DATABASE   CHARACTER   SET必须有SYSDBA权限,并且在STARTUP   RESTRICT模式下执行 
2、原字符集必须是目标字符集的一个真子集(就是浪子所说的只能从WE8ISO8859P1转到ZHS16GBK的原因) 
3、CLOB字段装换可能有问题,建议在转换以前把有CLOB字段的表导出后DROP,转换以后再导回 
4、该转换不可逆,所以在做这个操作以前建议做数据库全备份 

 

http://topic.csdn.net/u/20090507/14/c25568bb-b61f-4cf3-84ae-5110e14dbc92.html

呵呵呵刚看到一个简单的

SQL> select userenv(’language’) from dual;

http://topic.csdn.net/u/20080822/15/a62ac1ca-b7d4-4791-a3af-98355c72f909.html

执行这条SQL语句:

SQL code
select userenv('language') from dual

 

 

http://www.linuxidc.com/Linux/2011-04/34359p2.htm

http://www.eygle.com/archives/2004/09/nls_character_set_07.html

前面我们提到,通过修改props$的方式更改字符集在Oracle7之后是一种极其危险的方式,应该尽量避免。

我们又知道,通过ALTER DATABASE CHARACTER SET更改字符集虽然安全可靠,但是有严格的子集和超集的约束,实际上我们很少能够
用到这种方法。


实际上Oracle还存在另外一种更改字符集的方式.

如果你注意过的话,在Oracle的alert<sid>.log文件中,你可能看到过这样的日志信息:

alter database character set INTERNAL_CONVERT ZHS16GBK
Updating character set in controlfile to ZHS16GBK
 SYS.SNAP$ (REL_QUERY) - CLOB representation altered
 SYS.METASTYLESHEET (STYLESHEET) - CLOB representation altered
 SYS.EXTERNAL_TAB$ (PARAM_CLOB) - CLOB representation altered
 XDB.XDB$RESOURCE (SYS_NC00027$) - CLOB representation altered
 ODM.ODM_PMML_DTD (DTD) - CLOB representation altered
 OE.WAREHOUSES (SYS_NC00003$) - CLOB representation altered
 PM.ONLINE_MEDIA (SYS_NC00042$) - CLOB representation altered
 PM.ONLINE_MEDIA (SYS_NC00062$) - CLOB representation altered
 PM.ONLINE_MEDIA (PRODUCT_TEXT) - CLOB representation altered
 PM.ONLINE_MEDIA (SYS_NC00080$) - CLOB representation altered
 PM.PRINT_MEDIA (AD_SOURCETEXT) - CLOB representation altered
 PM.PRINT_MEDIA (AD_FINALTEXT) - CLOB representation altered
Completed: alter database character set INTERNAL_CONVERT ZHS1


 

在这里面,我们看到这样一条重要的,Oracle非公开的命令:

alter database character set INTERNAL_CONVERT/ INTERNAL_USE ZHS16GBK
                      

 

这个命令是当你选择了使用典型方式创建了种子数据库以后,Oracle会根据你选择的字符集设置,把当前种子数据库的字符集更改为期望字符
集,这就是这条命令的作用.

在使用这个命令时,Oracle会跳过所有子集及超集的检查,在任意字符集之间进行强制转换,所以,使用这个命令时你必须十分小心,你必须
清楚这一操作会带来的风险.
我们之前讲过的内容仍然有效,你可以使用csscan扫描整个数据库,如果在转换的字符集之间确认没有严重的数据损坏,或者你可以使用有效
的方式更改,你就可以使用这种方式进行转换.
我们来看一下具体的操作过程及Oracle的内部操作:

SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup mount
ORACLE instance started.

Total System Global Area  135337420 bytes
Fixed Size                   452044 bytes
Variable Size             109051904 bytes
Database Buffers           25165824 bytes
Redo Buffers                 667648 bytes
Database mounted.

SQL> ALTER SYSTEM ENABLE RESTRICTED SESSION;

System altered.

SQL> ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0;

System altered.

SQL> ALTER SYSTEM SET AQ_TM_PROCESSES=0;

System altered.

SQL> ALTER DATABASE OPEN;

Database altered.

SQL> alter session set events '10046 trace name context forever,level 12';

Session altered.

SQL> alter database character set INTERNAL_USE ZHS16CGB231280

Database altered.

SQL>
                      

 

这是alert.log文件中的记录信息:

Tue Oct 19 16:26:30 2004
Database Characterset is ZHS16GBK
replication_dependency_tracking turned off (no async multimaster replication found)
Completed: ALTER DATABASE OPEN
Tue Oct 19 16:27:07 2004
alter database character set INTERNAL_USE ZHS16CGB231280
Updating character set in controlfile to ZHS16CGB231280
Tue Oct 19 16:27:15 2004
Thread 1 advanced to log sequence 118
Current log# 2 seq# 118 mem# 0: /opt/oracle/oradata/primary/redo02.log
Tue Oct 19 16:27:15 2004
ARC0: Evaluating archive log 3 thread 1 sequence 117
ARC0: Beginning to archive log 3 thread 1 sequence 117
Creating archive destination LOG_ARCHIVE_DEST_1: '/opt/oracle/oradata/primary/archive/1_117.dbf'
ARC0: Completed archiving log 3 thread 1 sequence 117
Tue Oct 19 16:27:20 2004
Completed: alter database character set INTERNAL_USE ZHS16CGB231280
Shutting down instance: further logons disabled
Shutting down instance (immediate)
License high water mark = 1
Tue Oct 19 16:29:06 2004
ALTER DATABASE CLOSE NORMAL
...

格式化10046跟踪文件,得到以下信息(摘要):

alter session set events '10046 trace name context forever,level 12'


alter database character set INTERNAL_USE ZHS16CGB231280


call     count       cpu    elapsed       disk      query    current        rows
------- ------  -------- ---------- ---------- ---------- ----------  ----------
Parse        1      0.00       0.00          0          0          0           0
Execute      1      4.88       6.04        910      16825      18099           0
Fetch        0      0.00       0.00          0          0          0           0
------- ------  -------- ---------- ---------- ---------- ----------  ----------
total        2      4.88       6.04        910      16825      18099           0

Misses in library cache during parse: 1
Optimizer goal: CHOOSE
Parsing user id: SYS

Elapsed times include waiting on following events:
  Event waited on                             Times   Max. Wait  Total Waited
  ----------------------------------------   Waited  ----------  ------------
  control file sequential read                    4        0.00          0.00
  control file parallel write                     2        0.05          0.08
  log file sync                                   2        0.08          0.08
  SQL*Net message to client                       1        0.00          0.00
  SQL*Net message from client                     1       18.06         18.06
********************************************************************************

....

update col$ set charsetid = :1 
where
 charsetform = :2

....

update argument$ set charsetid = :1 
where
 charsetform = :2

....

update collection$ set charsetid = :1 
where
 charsetform = :2

....

update attribute$ set charsetid = :1 
where
 charsetform = :2
....

update parameter$ set charsetid = :1 
where
 charsetform = :2
....

update result$ set charsetid = :1 
where
 charsetform = :2

....

update partcol$ set spare1 = :1 
where
 charsetform = :2

....

update subpartcol$ set spare1 = :1 
where
 charsetform = :2

....

update props$ set value$ = :1 
where
 name = :2

....

update "SYS"."KOTAD$" set SYS_NC_ROWINFO$ = :1 
where
 SYS_NC_OID$ = :2
....

update seq$ set increment$=:2,minvalue=:3,maxvalue=:4,cycle#=:5,order$=:6,
  cache=:7,highwater=:8,audit$=:9,flags=:10 
where
 obj#=:1

....

update kopm$ set metadata = :1,  length 
  = :2 
where
 name='DB_FDO'

....

ALTER DATABASE CLOSE NORMAL
                      

此处生成的日志你可以在这里下载(供参考):

http://www.eygle.com/special/primary_ora_13730.zip
http://www.eygle.com/special/primary_ora_13730.tkf.log

我们看到这个过程和之前ALTER DATABASE CHARACTER SET操作的内部过程是完全相同的,也就是说INTERNAL_USE提供的帮助就是使
Oracle数据库绕过了子集与超集的校验.
这一方法在某些方面是有用处的,比如测试;应用于产品环境大家应该格外小心,除了你以外,没有人会为此带来的后果负责:

结语(我们不妨再说一次):

对于DBA来说,有一个很重要的原则就是:不要把你的数据库置于危险的境地!

这就要求我们,在进行任何可能对数据库结构发生改变的操作之前,先做有效的备份,很多DBA没有备份的操作中得到了惨痛的教训。

http://blog.csdn.net/lvzhiyuan/article/details/2167296

1、查看数据库字符集

数据库服务器字符集select * from nls_database_parameters,其来源于props$,是表示数据库的字符集。
  
  客户端字符集环境select * from nls_instance_parameters,其来源于v$parameter,
  
  表示客户端的字符集的设置,可能是参数文件,环境变量或者是注册表
  
  会话字符集环境 select * from nls_session_parameters,其来源于v$nls_parameters,表示会话自己的设置,可能是会话的环境变量或者是alter session完成,如果会话没有特殊的设置,将与nls_instance_parameters一致。
  
  客户端的字符集要求与服务器一致,才能正确显示数据库的非Ascii字符。如果多个设置存在的时候,alter session>环境变量>注册表>参数文件
  
  字符集要求一致,但是语言设置却可以不同,语言设置建议用英文。如字符集是zhs16gbk,则nls_lang可以是American_America.zhs16gbk。

2、修改字符集
8i以上版本可以通过alter database来修改字符集,但也只限于子集到超集,不建议修改props$表,将可能导致严重错误。
  
  Startup nomount;
  Alter database mount exclusive;
  Alter system enable restricted session;
  Alter system set job_queue_process=0;
  Alter database open;
  Alter database character set zhs16gbk;

3、怎么查看数据库版本

select * from v$version  

  包含版本信息,核心版本信息,位数信息(32位或64位)等  

  至于位数信息,在Linux/unix平台上,可以通过file查看,如  

  file $ORACLE_HOME/bin/oracle

 

http://fanlb.blogbus.com/logs/30128319.html

修改数据库字符集为:ZHS16GBK
查看服务器端字符集
SQL > select * from V$NLS_PARAMETERS
修改:
$sqlplus /nolog
SQL>conn / as sysdba~
若此时数据库服务器已启动,则先执行 SHUTDOWN IMMEDIATE 命
令关闭数据库服务器,然后执行以下命令:
SQL>shutdown immediate~
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 ZHS16GBK~
*
ERROR at line 1:
ORA-12721: operation cannot execute when other sessions are active
若出现上面的错误,使用下面的办法进行修改,使用INTERNAL_USE可以跳过超集的检查:
SQL>ALTER DATABASE CHARACTER SET INTERNAL_USE ZHS16GBK~
SQL>SHUTDOWN IMMEDIATE~
SQL>STARTUP

 

 

 

 

 

Oracle gb2312 字符集 转 utf-8

最近因为一些特殊的需求,考虑到以后系统的开发,
就把现有Oracle数据库的字符集gb2312改为了UTF-8
步骤:
1.在SQL*PLUS 中,以DBA登录
conn 用户名 as sysdba
2.执行转换语句:
SHUTDOWN IMMEDIATE;
STARTUP MOUNT EXCLUSIVE;
ALTER SYSTEM ENABLE RESTRICTED SESSION;
ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0;
ALTER SYSTEM SET AQ_TM_PROCESSES=0;
ALTER DATABASE OPEN;
ALTER DATABASE NATIONAL CHARACTER SET UTF8;
SHUTDOWN immediate;
startup;

注意:如果没有大对象,在使用过程中进行语言转换没有什么影响,(切记设定的字符集必须是ORACLE支持,不然不能start)

按上面的做法就可以,但是可能会出现‘ORA-12717: Cannot ALTER DATABASE NATIONAL CHARACTER SET when
NCLOB data exists’ 这样的提示信息

要解决这个问题有两种方法

一个是,利用INTERNAL_USE 关键字修改区域设置,
还有一个是利用re-create,但是re-create有点复杂,所以请用internal_use,

SHUTDOWN IMMEDIATE;
STARTUP MOUNT EXCLUSIVE;
ALTER SYSTEM ENABLE RESTRICTED SESSION;
ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0;
ALTER SYSTEM SET AQ_TM_PROCESSES=0;
ALTER DATABASE OPEN;
ALTER DATABASE NATIONAL CHARACTER SET INTERNAL_USE UTF8;
SHUTDOWN immediate;
startup;

如果按上面的做法做,National charset的区域设置就没有问题

 

http://blog.csdn.net/cyx_java/article/details/5319026

原来我用的oracle10g 一个汉字占三个字节,想修改成占两个字节,一查才知道是字符集的原因,

select userenv('language') from demo; -- demo是表名

结果为:

SIMPLIFIED CHINESE_CHINA.AL32UTF8

所以要修改字符集。

修改为 ZHS16GBK

 

如果直接修改:alter database character set ZHS16GBK

则会出现如下错误:

   alter database character set ZHS16GBK
   *
   第 1 行出现错误: 
   ORA-12712: 新字符集必须为旧字符集的超集

 

 

所以采用下面的方法修改字符集:

 

以DBA身份进入SQLPLUS

SQL> sqlplus sys/sys as sysdba;

……

SQL> shutdown immediate;
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;(AL32UTF8)
SQL> shutdown immediate;
SQL> startup;

 

http://unix-cd.com/vc/www/16/2011-01/17686.html

下面说明如何在10g用修改字符集。
1、当前字符集
sys@TEST> select userenv('language') from dual;                                                                                     
                                                                                                                                    
USERENV('LANGUAGE')                                                      
------------------------------------------------------                         
SIMPLIFIED CHINESE_CHINA.ZHS16CGB231280                           
2、插入一些生僻字
sys@TEST> create table a(a varchar2(100));
表已创建。
sys@TEST> insert into a values('珮');
已创建 1 行。
sys@TEST> commit;
提交完成。
sys@TEST> select *from a;
A
--------------------
可见,ZHS16CGB231280包含的汉字太少,需要升级包含汉字更多的ZHS16GBK。ZHS16GBK是ZHS16CGB231280的超集,可以直接修改字符集。
3、关闭数据库并备份
    由于更新数据库操作不可回滚,安全起见,最好对数据库做一个全备。
4、使用csscan检查字符集转换是否可行
    csscan扫描数据库的所有数据并测试字符集转换是否可行。
    csscan有四种扫描模式:全库扫描、按用户扫描、按表扫描、按列扫描。
    因为我们这里是测试改变全库的字符集,所以要用全库扫描模式,并且要求扫描用户有DBA权限:

                    
                    运行csscan需要一系列的权限和表,因此需要先运行一个脚本,否则会报错:
                    sys@TEST> @/opt/oracle/10gapp/rdbms/admin/csminst.sql
                    ......
                    
                    
                    视图已创建。
                    
                    
                    同义词已删除。
                    
                    
                    同义词已创建。
                    
                    
                    视图已创建。
                    
                    
                    视图已创建。
                    
                    
                    提交完成。
                    
                    从 Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
                    With the Partitioning, Oracle Label Security, OLAP and Data Mining options 断开
                    
                    运行CSSCAN扫描数据库:
                    [oracle@localhost admin]$/opt/oracle/10gapp/bin/CSSCAN  SYSTEM/AAA FULL=y FROMCHAR=ZHS16CGB231280 TOCHAR=ZHS16GBK ARRAY=1024000 PROCESS=1
                        简单说一下几个参数的含义:
                                        username/password :数据库用户名和口令,需要有dba权限
                                        FULL                          :是否进行全库扫描
                                        FROMCHAR                  :原字符集,可以省略,默认为连接数据库的当前字符集
                                        TOCHAR                        :目标字符集
                                        ARRAY                            :读取数据的缓冲区大小
                                        PROCESS                        :同时启动几个进程进行扫描
                    
                    Character Set Scanner v2.1 : Release 10.2.0.0.0 - Production on 星期四 12月 27 18:49:55 2007
                    
                    Copyright (c) 1982, 2005, Oracle.  All rights reserved.
                    
                    Connected to:
                    Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
                    With the Partitioning, Oracle Label Security, OLAP and Data Mining options
                    
                    Enumerating tables to scan...
                    .......
                    . process 1 scanning SYS.WRH$_LATCH_MISSES_SUMMARY[AAACUwAADAAAAzRAAA]
                    . process 1 scanning SYSTEM.LOGMNR_COL$[AAABbGAADAAAAeZAAA]
                    . process 1 scanning SYSTEM.LOGMNR_ATTRCOL$[AAABa/AADAAAAhpAAA]
                    ......
                    Creating Database Scan Summary Report...
                    
                    Creating Individual Exception Report...
                    
                    Scanner terminated successfully.
                    
                    默认情况下,csscan扫描结束后,会产生三个文件:scan.txt、scan.err、scan.out,分别查看这三个文件,如果没有异常,则可以往下执行了。
                    
                    csscan会把最近一次执行扫描的参数写入表csm$parameters中,这个表的参数非常重要,它决定着下一步进行字符集转换需要的参数,如要转成什么字符集等。
                    sys@TEST> select * from csm$parameters;
                    
                    NAME                           VALUE
                    ------------------------------ ----------------------------------------
                    SCANNER_VERSION                5
                    SCAN_TYPE                      ALL
                    SCAN_CHAR                      YES
                    TO_CHARSET_NAME                ZHS16GBK
                    FROM_CHARSET_NAME              ZHS16CGB231280
                    SCAN_NCHAR                     NO
                    MAX_ARRAY_SIZE                 1024000
                    MAX_ROWS_IN_HEAP               100
                    NUMBER_OF_PROCESS              1
                    SUPPRESS_ERROR_LOG_BY          -1
                    INSERT_SUPPRESSED              NO
                    CAPTURE_CONVERTIBLE_DATA       NO
                    SCANNER_SCRIPT                 NO
                    SCANNER_PRESERVE               NO
                    MIGRATE_TO_SUPERSET            0
                    CSLD_ENABLE                    0
                    PREVIOUS_CHARACTER_SET         ZHS16CGB231280
                    PREVIOUS_NCHAR_SET             AL16UTF16
                    TIME_START                     2007-12-27 18:50:02
                    TIME_END                       2007-12-27 18:51:35

5、运行CSALTER修改字符集
    CSALTER是10g新推出的用于修改oracle字符集的工具,它位于$ORACLE_HOME/RDBMS/ADMIN/中,其实这个工具并不神秘,它只不过是把文章开头提到的9i中修改字符集的主要步骤写成脚本,并新增一些自动检查功能,简化操作并尽量避免错误产生。
                sys@TEST> @/opt/oracle/10gapp/rdbms/admin/CSALTER.PLB
                
                已创建0行。
                
                
                函数已创建。
                
                
                函数已创建。
                
                
                过程已创建。
                
                This script will update the content of the Oracle Data Dictionary.
                Please ensure you have a full backup before initiating this procedure.
                Would you like to proceed (Y/N)?y
                原值    6:     if (UPPER('&conf') <> 'Y') then
                新值    6:     if (UPPER('y') <> 'Y') then
                Checking data validility...
                begin converting system objects
                
                PL/SQL 过程已成功完成。
                
                Alter the database character set...
                CSALTER operation completed, please restart database
                
                PL/SQL 过程已成功完成。
                
                
                已删除0行。
                
                
                函数已删除。
                
                
                函数已删除。
                
                
                过程已删除。
这里注意到,oracle并没有要求我们输入参数来执行要把当前数据库字符集转换为什么字符集,实际上,CSALERT读取csm$parameters中设定的参数值来进行字符集转换。
这个操作会很快完成,因为csalter并没有修改实际数据,只是把数据字典中的元数据修改一下而已。
从后台日志可以看出这个过程执行的操作:
                Thu Dec 27 22:25:43 2007
                ALTER SYSTEM enable restricted session;
                MMNL started with pid=11, OS id=3516
                Thu Dec 27 22:25:43 2007
                ALTER SYSTEM SET job_queue_processes=0 SCOPE=BOTH;
                Thu Dec 27 22:25:43 2007
                ALTER SYSTEM SET aq_tm_processes=0 SCOPE=BOTH;
                Thu Dec 27 22:25:43 2007
                alter database character set internal_use ZHS16GBK
                Thu Dec 27 22:25:46 2007
                Updating character set in controlfile to ZHS16GBK
                Synchronizing connection with database character set information
                Refreshing type attributes with new character set information
                Completed: alter database character set internal_use ZHS16GBK
6、重启数据库
            sys@TEST> shutdown immediate
            数据库已经关闭。
            已经卸载数据库。
            ORACLE 例程已经关闭。
            sys@TEST> startup
            ORACLE 例程已经启动。
            
            Total System Global Area  603979776 bytes
            Fixed Size                  1250380 bytes
            Variable Size             159386548 bytes
            Database Buffers          436207616 bytes
            Redo Buffers                7135232 bytes
            数据库装载完毕。
            数据库已经打开。
7、验证
            sys@TEST> select userenv('language') from dual;
            
            USERENV('LANGUAGE')
            ----------------------------------------------------
            SIMPLIFIED CHINESE_CHINA.ZHS16GBK
--可见,数据库字符集已经变为ZHS16GBK了。
再查原来是乱码的数据:
            sys@TEST> select * from a;
            
            A
            ----------
            ?
查询结果是乱码,这也就是说对于原来库中已经是乱码的数据,修改字符集是无能为力的。
我们再看看此时是否可以插入原来是乱码的汉字:
            sys@TEST> insert into a values('珮');
            
            已创建 1 行。
            
            sys@TEST> select * from a;
            
            A
            ----------
            ?
            珮
原来是乱码的汉字现在可以正常插入和显示,字符集修改成功。
 

如何修改oracle 10g的字符集

查看服务器端字符集: SQL > select * from V$NLS_PARAMETERS;

 

  修改数据库字符集为:ZHS16GBK

  查看服务器端字符集

 


  SQL > select * from V$NLS_PARAMETERS;

 

  修改:

 


  $sqlplus /nolog 
  SQL>conn / as sysdba

 

  若此时数据库服务器已启动,则先执行 SHUTDOWN IMMEDIATE 命

  令关闭数据库服务器,然后执行以下命令:

 


  SQL>shutdown immediate 
  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 ZHS16GBK 
  * 
  ERROR at line 1: 
  ORA-12721: operation cannot execute when other sessions are active

 

  若出现上面的错误,使用下面的办法进行修改,使用INTERNAL_USE可以跳过超集的检查:

 


  SQL>ALTER DATABASE CHARACTER SET INTERNAL_USE ZHS16GBK; 
  SQL>SHUTDOWN IMMEDIATE 
  SQL>STARTUP
 
查看当前字符集 
引用
SQL> select * from nls_database_parameters where parameter like '%SET%'; 

PARAMETER                      VALUE 
------------------------------ ---------------------------------------- 
NLS_CHARACTERSET               WE8ISO8859P1 
NLS_NCHAR_CHARACTERSET         AL16UTF16 


引用
SQL> select userenv('language') from dual; 

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


尝试直接修改字符集 
引用
SQL> 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 10g中建议用CSALTER修改!) 
引用
SQL> shutdown immediate 
Database closed. 
Database dismounted. 
ORACLE instance shut down. 
SQL> startup mount 
ORACLE instance started. 

Total System Global Area  167772160 bytes 
Fixed Size                  1218316 bytes 
Variable Size              62916852 bytes 
Database Buffers          100663296 bytes 
Redo Buffers                2973696 bytes 
Database mounted. 
SQL> ALTER SYSTEM ENABLE RESTRICTED SESSION; 

SQL> ALTER SYSTEM ENABLE RESTRICTED SESSION;                         

System altered. 

SQL> ALTER SYSTEM SET JOB_QUEUE_PROCESSES=0; 

System altered. 

SQL> ALTER SYSTEM SET AQ_TM_PROCESSES=0; 

System altered. 

SQL>  ALTER DATABASE OPEN; 

Database altered. 

SQL> ALTER DATABASE CHARACTER SET INTERNAL_USE zhs16gbk; 

Database altered.

修改时alert日志显示: 
引用
Completed:  ALTER DATABASE OPEN 
Tue May 18 10:56:43 2010 
ALTER DATABASE CHARACTER SET INTERNAL_USE zhs16gbk 
Tue May 18 10:56:47 2010 
Updating character set in controlfile to ZHS16GBK 
Synchronizing connection with database character set information 
Refreshing type attributes with new character set information 
Completed: ALTER DATABASE CHARACTER SET INTERNAL_USE zhs16gbk

查看修改后结果: 
引用
SQL> select * from nls_database_parameters where parameter like '%SET%'; 

PARAMETER 
------------------------------ 
VALUE 
-------------------------------------------------------------------------------- 
NLS_CHARACTERSET 
ZHS16GBK 

NLS_NCHAR_CHARACTERSET 
AL16UTF16


引用

SQL> select userenv('language') from dual; 

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

关于这个问题,网络上有很多修改Oracle字符集的方法,但是真正能够操作或适用的并不多,下面就转载一个相当有用的

 

一、常规方法修改数据库字符集
 
当前数据库字符集:
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               US7ASCII
......
 
20 rows selected.
 
SQL> conn zwfha/admin
Connected.
SQL> select * from tab;
 
TNAME                          TABTYPE  CLUSTERID
------------------------------ ------- ----------
HRMS_EMPINFO_COMPANY           TABLE
HRMS_EMPINFO_DEPARTMENT        TABLE
HRMS_EMPINFO_DIRECTOR          TABLE
HRMS_EMPINFO_EDUCATION         TABLE
HRMS_EMPINFO_EMPLOYEE          TABLE
HRMS_EMPINFO_EXPERIENCE        TABLE
HRMS_EMPINFO_FAMILY            TABLE
HRMS_EMPINFO_HONOR             TABLE
HRMS_EMPINFO_JOB               TABLE
HRMS_EMPINFO_STATUS            TABLE
HRMS_EMPINFO_TEAM              TABLE
 
11 rows selected.

关闭数据库,打开到mount状态,准备修改数据库字符集(修改前最好备份一下)
 
SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL>
SQL> startup mount
ORACLE instance started.
 
Total System Global Area  117440512 bytes
Fixed Size                   787728 bytes
Variable Size              91224816 bytes
Database Buffers           25165824 bytes
Redo Buffers                 262144 bytes
Database mounted.
SQL>
SQL> alter system enable restricted session;
 
System altered.
 
SQL> show parameter processes
 
NAME                                 TYPE        VALUE
------------------------------------ ----------- --------------------
aq_tm_processes                      integer     0
db_writer_processes                  integer     1
gcs_server_processes                 integer     0
job_queue_processes                  integer     10
log_archive_max_processes            integer     2
processes                            integer     150
SQL>
SQL> alter system set job_queue_processes=0;
 
System altered.
 
SQL> alter system set aq_tm_processes=0;
 
System altered.
 
SQL> alter database open;
 
Database altered.
 
SQL> alter database character set zhs16gbk;
alter database character set zhs16gbk
*
ERROR at line 1:
ORA-12716: Cannot ALTER DATABASE CHARACTER SET when CLOB data exists
 
----
alter信息:
Wed Jan 16 13:54:36 2008
 SYS.METASTYLESHEET (STYLESHEET) - CLOB populated
ORA-12716 signalled during: alter database character set zhs16gbk...
----
这里参考eygle的修改字符集文章(http://www.eygle.com/special/NLS_CHARACTER_SET_03.htm)
 
SQL> truncate table Metastylesheet;
 
Table truncated.
 
SQL> alter database character set zhs16gbk;
alter database character set zhs16gbk
*
ERROR at line 1:
ORA-12716: Cannot ALTER DATABASE CHARACTER SET when CLOB data exists
 
----
alert信息:
Wed Jan 16 13:57:07 2008
alter database character set zhs16gbk
Wed Jan 16 13:57:07 2008
 SYS.RULE$ (CONDITION) - CLOB populated
ORA-12716 signalled during: alter database character set zhs16gbk...
----
看来9.2跟10的差别还是很大嘞。。要小心啊。
 
使用internal_convert来修改
 
SQL> alter database character set internal_convert zhs16gbk;
 
Database altered.
alert里面可以看到,ORACLE会自动转换含有CLOB字段的表
----
alert信息:
Wed Jan 16 14:06:12 2008
alter database character set internal_convert zhs16gbk
Wed Jan 16 14:06:15 2008
Private_strands 7 at log switch
Thread 1 advanced to log sequence 38
  Current log# 2 seq# 38 mem# 0: D:\ORACLE\ORADATA\ORCL\REDO02.LOG
Wed Jan 16 14:06:16 2008
Updating character set in controlfile to ZHS16GBK
Synchronizing connection with database character set information
Wed Jan 16 14:06:16 2008
Published database character set on system events channel
Wed Jan 16 14:06:16 2008
All processes have switched to database character set
 SYS.WRI$_DBU_HWM_METADATA (LOGIC) - CLOB representation altered
 SYS.WRI$_DBU_FEATURE_METADATA (INST_CHK_LOGIC) - CLOB representation altered
 SYS.WRI$_DBU_FEATURE_METADATA (USG_DET_LOGIC) - CLOB representation altered
 SYS.WRI$_DBU_FEATURE_USAGE (FEATURE_INFO) - CLOB representation altered
 SYS.SCHEDULER$_EVENT_LOG (ADDITIONAL_INFO) - CLOB representation altered
 SYS.RULE$ (CONDITION) - CLOB representation altered
Refreshing type attributes with new character set information
Completed: alter database character set internal_convert zhs1
----
 
因为前面清空了SYS.METASTYLESHEET表,需要重新创建
9.2通过@?/rdbms/admin/catmet.sql创建;
10g中没有catmet.sql这个脚本,通过运行catmeta.sql脚本来重建
@?/rdbms/admin/catmeta.sql
(注意这个地方有待商榷,不确定,最好不要使用这种方法修改)
 
shutdown
startup

至此,修改正常。

二、使用internal_convert修改数据库字符集
 
SQL> startup mount
ORACLE instance started.
 
Total System Global Area  117440512 bytes
Fixed Size                   787728 bytes
Variable Size              91224816 bytes
Database Buffers           25165824 bytes
Redo Buffers                 262144 bytes
Database mounted.
SQL> show parameter processes
 
NAME                                 TYPE        VALUE
------------------------------------ ----------- --------------------------
aq_tm_processes                      integer     10
db_writer_processes                  integer     1
gcs_server_processes                 integer     0
job_queue_processes                  integer     10
log_archive_max_processes            integer     2
processes                            integer     150
 
 
打开数据库到restricted状态
 
SQL> alter system enable restricted session;
 
System altered.
 
SQL> alter database open;
 
Database altered.
 
查看当前数据库字符集:
SQL> col name for a30
SQL> col value$ for a30
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               US7ASCII
......
 
20 rows selected.
 
这里为了方便区分trace文件名,把trace文件加上标识
 
SQL> alter session set tracefile_identifier='cs';
 
Session altered.
 
SQL> alter session set sql_trace=true;
 
Session altered.
 
SQL> alter database character set internal_convert zhs16gbk;
--SQL> ALTER DATABASE character set INTERNAL_USE ZHS16GBK;--跳过超集检查
Database altered.
 
alert信息:
~~~~~~~~~~~~~~~~~~~~~
Wed Jan 16 14:49:47 2008
alter database character set internal_convert zhs16gbk
Wed Jan 16 14:49:50 2008
Private_strands 7 at log switch
Thread 1 advanced to log sequence 38
  Current log# 2 seq# 38 mem# 0: D:\ORACLE\ORADATA\ORCL\REDO02.LOG
Wed Jan 16 14:49:52 2008
Updating character set in controlfile to ZHS16GBK
Synchronizing connection with database character set information
Wed Jan 16 14:49:52 2008
Published database character set on system events channel
 SYS.WRI$_DBU_HWM_METADATA (LOGIC) - CLOB representation altered
 SYS.WRI$_DBU_FEATURE_METADATA (INST_CHK_LOGIC) - CLOB representation altered
 SYS.WRI$_DBU_FEATURE_METADATA (USG_DET_LOGIC) - CLOB representation altered
 SYS.WRI$_DBU_FEATURE_USAGE (FEATURE_INFO) - CLOB representation altered
 SYS.SCHEDULER$_EVENT_LOG (ADDITIONAL_INFO) - CLOB representation altered
 SYS.RULE$ (CONDITION) - CLOB representation altered
 SYS.METASTYLESHEET (STYLESHEET) - CLOB representation altered
Refreshing type attributes with new character set information
 
alert中的信息与上面的相同,ORACLE在内部转换CLOB字段相关的表为新字符集,这个在trace文件中可以很清楚得看到。
这里就不贴trace信息了。有兴趣自己trace一下。
 
查看修改后的字符集:
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
......
 
SQL> alter system disable restricted session;
 
System altered.
 
D:\>set NLS_LANG=american_america.ZHS16GBK
 
D:\>
D:\>sqlplus zwfha/admin
SQL> select name from HRMS_EMPINFO_JOB where rownum<3;
 
NAME
----------------------------------------
总裁
总监
 
SQL> create table t(name varchar2(200));
 
Table created.
 
SQL>
SQL> insert into t values('在过程里就是吧条件用参数传入');
 
1 row created.
 
SQL> commit;
 
Commit complete.
 
SQL> select * from t;
 
NAME
----------------------------------------
在过程里就是吧条件用参数传入
 
到此,字符集修改完成。这个与上面修改属于同一类型。只不过更加简单明了而已.

 

http://www.baoluowanxiang.com/database/oracle/2012-05-11/653.html

 

在国内外大中型数据库管理系统中,把ORACLE作为数据库管理平台的用户比较多。ORACLE 不论是数据库管理能力还是安全性都是无可非议的,但是,它在汉字信息的显示方面着实给中国用户带来不少麻烦,笔者多年从事ORACLE数据库管理,经常收到周围用户和外地用户反映有关ORACLE数据库汉字显示问题的求援信,主要现象是把汉字显示为不可识别的乱码,造成原来大量信息无法使用。本文将就这一问题产生的原因和解决办法进行一些探讨,供存在这方面问题的用户朋友参考。

 

1、原因分析

 

通过对用户反映情况的分析,发现字符集的设置不当是影响ORACLE数据库汉字显示的关键问题。那么字符集是怎么一会事呢?字符集是ORACLE 为适应不同语言文字显示而设定的。用于汉字显示的字符集主要有ZHS16CGB231280,US7ASCII,WE8ISO8859P1等。字符集不仅需在服务器端存在,而且客户端也必须有字符集注册。服务器端,字符集是在安装ORACLE时指定的,字符集登记信息存储在ORACLE数据库字典的V$NLS_PARAMETERS表中;客户端,字符集分两种情况,一种情况是sql*net 2.0以下版本,字符集是在windows的系统目录下的oracle.ini文件中登记的;另一种情况是sql*net 2.0以上(即32位)版本,字符集是在windows的系统注册表中登记的。要在客户端正确显示ORACLE 数据库汉字信息,首先必须使服务器端的字符集与客户端的字符集一致;其次是加载到ORACLE数据库的数据字符集必须与服务器指定字符集一致。因此,把用户存在的问题归纳分类,产生汉字显示异常的原因大致有以下几种:

 

1. 1服务器指定字符集与客户字符集不同,而与加载数据字符集一致。

 

这种情况是最常见的,只要把客户端的字符集设置正确即可,解决办法见2.1。

 

1. 2服务器指定字符集与客户字符集相同,与加载数据字符集不一致。

 

这类问题一般发生在ORACLE版本升级或重新安装系统时选择了与原来服务器端不同的字符集,而恢复加载的备份数据仍是按原字符集卸出的场合,以及加载从其它使用不同字符集的ORACLE数据库卸出的数据的情况。这两种情况中,不管服务器端和客户端字符集是否一致都无法显示汉字。解决办法见2.2。

 

1.3服务器指定字符集与客户字符集不同,与输入数据字符集不一致。

 

这种情况是在客户端与服务器端字符集不一致时,从客户端输入了汉字信息。输入的这些信息即便是把客户端字符集更改正确,也无法显示汉字。解决办法见2.3。

 

2.解决办法

 

下面将分别对上述三种情况给出解决办法。为了叙述方便,假设客户端使用WINDOWS95/98环境,并已成功地配置了TCP/IP协议,安装了ORACLE的sql*net,sql*pluse产品。

 

2.1 设置客户端字符集与服务器端字符集一致

 

假设当前服务器端使用US7ASCII字符集。

 

(1)查看服务器端字符集

 

通过客户端或服务器端的sql*plus登录ORACLE的一个合法用户,执行下列SQL语句:

 

SQL > select * from V$NLS_PARAMETERS

 

或者

 

SQL > select * from NLS_DATABASE_PARAMETERS;

 

parameter value

 

NLS_LANGUAGE AMERICAN

 

NLS_TERRITORY AMERICA

 

… …

 

NLS_CHARACTERSET US7ASCII

 

NLS_SORT BINARY

 

NLS_NCHAR_CHARACTERSET US7ASCII

 

从上述列表信息中可看出服务器端ORACLE数据库的字符集为 'US7ASCII '。

 

===可以使用

 

export NLS_LANG="SIMPLIFIED CHINESE_CHINA.ZHS16GBK"

 

这只能在会话内生效,可以加到 oracle用户home目录/.bash_profile 内,是修改永久生效。

 

(2)按照服务器端字符集对客户端进行配置

 

配置方法有两种:

 

安装ORACLE的客户端软件时指定

 

在安装ORACLE的客户端产品软件时,选择与ORACLE服务端一致的字符集(本例为US7ASCII)即可。

 

修改注册信息的方法

 

根据ORACLE 客户端所选sql*net 的版本分为下列两种情况:

 

a. 客户端为 sql*net 2.0 以下版本

 

进入Windows的系统目录,编辑oracle.ini文件,用US7ASCII替换原字符集,重新启动计算机,设置生效。

 

b. 客户端为 sql*net 2.0 以上版本

 

在WIN98 下 运 行REGEDIT,第一步选HKEY_LOCAL_MACHINE,第二步选择SOFTWARE, 第三步选择 ORACLE, 第四步选择 NLS_LANG, 键 入 与服 务 器 端 相 同 的 字 符 集(本例为:AMERICAN_AMERICAN.US7ASCII)。

 

2.2 强制加载数据字符集与服务器端字符集一致

 

假设要加载数据从原ORACLE数据库卸出时的字符集为US7ASCII,当前ORACLE服务器字符集为WE8ISO8859P1。

 

下面提供三种解决方法:

 

(1) 服务器端重新安装ORACLE

 

在重新安装ORACLE 时选择与原卸出数据一致的字符集(本例为US7ASCII)。

 

加载原卸出的数据。

 

这种情况仅仅使用于空库和具有同一种字符集的数据。

 

(2)强行修改服务器端ORACLE当前字符集

 

在用imp命令加载数据前,先在客户端用sql*plus登录system DBA用户,执行下列SQL语句进行当前ORACLE数据库字符集修改:

 

SQL > create database character set US7ASCII

 

* create database character set US7ASCII

 

ERROR at line 1:

 

ORA-01031: insufficient privileges

 

你会发现语句执行过程中,出现上述错误提示信息,此时不用理会,实际上ORACLE数据库的字符集已被强行修改为US7ASCII,接着用imp命令装载数据。等数据装载完成以后,shutdown 数据库,再startup 数据库,用合法用户登录ORACLE数据库,在sql> 命令提示符下,运行select * from V$NLS_PARAMETERS,可以看到ORACLE数据库字符集已复原,这时再查看有汉字字符数据的表时,汉字已能被正确显示。

 

注:另一种办法:通过在在sqlplus内关闭数据库,在上面更改。

 

如下:

 

SIMPLIFIED CHINESE_CHINA.ZHS16GBK 包含 AMERICAN_AMERICA.AL32UTF8.

 

这可是个麻烦事,不是改客户端字符集的问题。要改数据库的字符集:

 

SQL> conn /as sysdba

 

SQL> shutdown immediate;

 

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 ZHS16GBK;

 

ERROR at line 1:

 

ORA-12712: new character set must be a superset of old character set

 

提示我们的字符集:新字符集必须为旧字符集的超集,这时我们可以跳过超集的检查做更改:

 

SQL> ALTER DATABASE character set INTERNAL_USE ZHS16GBK;

 

--我们看到这个过程和之前ALTER DATABASE CHARACTER SET操作的内部过程是完全相同的,也就是说INTERNAL_USE提供的帮助就是使Oracle数据库绕过了子集与超集的校验。

 

SQL> select * from v$nls_parameters;

 

SQL> shutdown immediate;

 

SQL> startup

 

SQL> select * from v$nls_parameters;

 

SQL> select userenv('language') from dual;

 

ok修改成功!

 

=====

 

(3)利用数据格式转储,避开字符集限制

 

这种方法主要用于加载外来ORACLE数据库的不同字符集数据。其方法如下:

 

先将数据加载到具有相同字符集的服务器上,然后用转换工具卸出为foxbase 格式或access格式数据库,再用转换工具转入到不同字符集的ORACLE数据库中,这样就避免了ORACLE字符集的困扰。目前数据库格式转换的工具很多,象power builder5.0以上版本提供的pipeline,Microsoft Access数据库提供的数据导入/导出功能等。转换方法参见有关资料说明。

 

2.3匹配字符集替换汉字

 

对于1.3提到的情况,没有很好的办法,只能先把客户端与服务器端字符集匹配一致后,根据原输入汉字的特征码替换汉字字符部分。

 

posted @ 2012-10-11 14:16  陳聽溪  阅读(818)  评论(0)    收藏  举报