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
sys@TEST> select userenv('language') from dual;
USERENV('LANGUAGE')
------------------------------------------------------
SIMPLIFIED CHINESE_CHINA.ZHS16CGB231280
--------------------
?
由于更新数据库操作不可回滚,安全起见,最好对数据库做一个全备。
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扫描数据库:
简单说一下几个参数的含义:
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行。
函数已删除。
函数已删除。
过程已删除。
这个操作会很快完成,因为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
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
数据库装载完毕。
数据库已经打开。
sys@TEST> select userenv('language') from dual;
USERENV('LANGUAGE')
----------------------------------------------------
SIMPLIFIED CHINESE_CHINA.ZHS16GBK
再查原来是乱码的数据:
sys@TEST> select * from a;
A
----------
?
已创建 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 |
PARAMETER VALUE
------------------------------ ----------------------------------------
NLS_CHARACTERSET WE8ISO8859P1
NLS_NCHAR_CHARACTERSET AL16UTF16
USERENV('LANGUAGE')
----------------------------------------------------
AMERICAN_AMERICA.WE8ISO8859P1
尝试直接修改字符集
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修改!)
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日志显示:
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
查看修改后结果:
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提到的情况,没有很好的办法,只能先把客户端与服务器端字符集匹配一致后,根据原输入汉字的特征码替换汉字字符部分。