Export done in US7ASCII character set and AL16UTF16 NCHAR character set
Character set和national character set分別代表數(shù)據(jù)庫字符集和國家字符集:
CREATE DATABASE zhangyu
MAXINSTANCES 1
MAXLOGHISTORY 1
MAXLOGFILES 5
MAXLOGMEMBERS 3
MAXDATAFILES 100
controlfile reuse
DATAFILE 'E:\zhangyu\oradata\zhangyu\system01.dbf' SIZE 250M REUSE
autoextend on
MAXSIZE UNLIMITED
sysaux datafile 'E:\zhangyu\oradata\zhangyu\sysaux01.dbf' size 200M
autoextend on
maxsize unlimited
DEFAULT TEMPORARY TABLESPACE TEMP TEMPFILE 'E:\zhangyu\oradata\zhangyu\temp01.dbf' SIZE 40M REUSE autoextend on
MAXSIZE UNLIMITED
UNDO TABLESPACE "UNDOTBS1" DATAFILE 'E:\zhangyu\oradata\zhangyu\undotbs01.dbf' SIZE 200M REUSE autoextend on
MAXSIZE UNLIMITED
CHARACTER SET ZHS16GBK
NATIONAL CHARACTER SET AL16UTF16
LOGFILE GROUP 1 ('E:\zhangyu\oradata\zhangyu\redo01.log') SIZE 102400K,
GROUP 2 ('E:\zhangyu\oradata\zhangyu\redo02.log') SIZE 102400K,
GROUP 3 ('E:\zhangyu\oradata\zhangyu\redo03.log') SIZE 102400K
國家字符集的作用就是來存儲(chǔ)nchar,nvarchar2,nclob等類似數(shù)據(jù)類型。
2)常見中文字符集:
sys@ZHANGYU>select parameter,value from v$nls_valid_values where upper(parameter)='CHARACTERSET' and ISDEPRECATED='FALSE' and value like 'ZH%';
查詢結(jié)果中zhs開頭的是simplified(簡(jiǎn)體中文的),zht開頭的是 Trad(繁體,傳統(tǒng)字體)。
另外看下字符參數(shù)命名規(guī)則:比如zhs16gbk,其中zhs代表語言,這里是簡(jiǎn)體中文;
16代表16bit(2byte),即可以代表2^16=65536-1個(gè)字符;
Gbk代表字符集。
再看us7ascii就代表美國,7bit,ascii字符集;
還有al6utf16代表所有語言通用(all),16個(gè)bit和utf16字符集等等.
3)字符集的轉(zhuǎn)換
Alter database character set
sys@ZHANGYU>alter database character set zhs16gbk;
alter database character set zhs16gbk
*
第 1 行出現(xiàn)錯(cuò)誤:
ORA-12719: 操作要求數(shù)據(jù)庫處于 RESTRICTED 模式下
且在轉(zhuǎn)換字符集之前一定要確定目標(biāo)字符集是當(dāng)前字符集的嚴(yán)格超集
嚴(yán)格超集的條件:
一個(gè)字符集里包含另一個(gè)字符集中的所有字符,并且相同字符的編碼要一樣;
滿足這兩個(gè)條件才行。
查看當(dāng)前非線性變量:
sys@ZHANGYU>select * from v$nls_parameters;
sys@ZHANGYU>select * from v$nls_parameters where parameter in('NLS_CHARACTERSET','NLS_NCHAR_CHARACTERSET');
改變字符集:
改變字符集前一定要確定字符間之間的超集關(guān)系,下面在我的庫上測(cè)試,由于不知道zhs16gbk的嚴(yán)格超集,所以沒有改變字符集,僅是演示下方式:
sys@ZHANGYU>startup mount;
sys@ZHANGYU>alter system set job_queue_processes=0;
sys@ZHANGYU>alter system set aq_tm_processes=0;
上面兩個(gè)參數(shù)我也不知道啥意思,照做就是;想了解的可以查下官方的reference;
sys@ZHANGYU>alter system enable restricted session;
sys@ZHANGYU>alter database open;
sys@ZHANGYU>exec dbms_monitor.session_trace_enable();
sys@ZHANGYU>alter database character set zhs16gbk;
sys@ZHANGYU>exec dbms_monitor.session_trace_disable();
啟動(dòng)另一個(gè)session:
sys@ZHANGYU>select b.spid from v$session a,v$process b where a.paddr=b.addr and a.username='SYS';
SPID
------------
3328
1656
sys@ZHANGYU>show parameter user_dump_dest
找到trace文件不是1656就是3328,總有一個(gè)的。
結(jié)果是1656:
Trcsess output=E:\test.trc session=325.3 E:\zhangyu\oradata\admin\zhangyu\udump\zhangyu_ora_1656.trc
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
等等,其實(shí)更新字符集就是更新這些數(shù)據(jù)字典表。
3)字符集對(duì)導(dǎo)入導(dǎo)出的影響:
在客戶端進(jìn)行導(dǎo)出文件時(shí),最好將客戶端的nls_lang設(shè)置成和數(shù)據(jù)庫端一樣的,這樣避免發(fā)生不必要的轉(zhuǎn)換。而將導(dǎo)出文件再導(dǎo)入到另一個(gè)數(shù)據(jù)庫時(shí),也同樣將客戶端的字符集設(shè)置成和數(shù)據(jù)庫端一樣的;
上面這樣做之后,通常只會(huì)最多發(fā)生一次數(shù)據(jù)庫字符集的轉(zhuǎn)換(很明顯)。
執(zhí)行導(dǎo)入時(shí)主要存在以下兩種情況:
源數(shù)據(jù)庫和目標(biāo)數(shù)據(jù)庫具有相同的字符集,這時(shí)只要設(shè)置nls_lang等于數(shù)據(jù)庫字符集即可,前提是導(dǎo)出使用的和前兩者一樣的,即三者字符集調(diào)協(xié)一樣,這樣就不需要進(jìn)行轉(zhuǎn)換。
源數(shù)據(jù)庫和目標(biāo)數(shù)據(jù)庫字符集不同時(shí),我們可以在導(dǎo)出時(shí)使用和數(shù)據(jù)庫一樣的字符集,而在導(dǎo)入時(shí)也是設(shè)置和導(dǎo)出時(shí)一樣的字符集,這樣字符集轉(zhuǎn)換只發(fā)生在目標(biāo)數(shù)據(jù)庫上一次。
下面進(jìn)行一將從演示:
確定源數(shù)據(jù)庫的字符集,只要進(jìn)行導(dǎo)出一個(gè)小的表就可以實(shí)現(xiàn):
C:\>echo %nls_lang%
american_america.us7ascii
C:\>exp scott/tiger file=e:\scott_dept.dmp tables=dept
Connected to: Personal Oracle Database 10g(個(gè)人版) Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
Export done in US7ASCII character set and AL16UTF16 NCHAR character set
server uses ZHS16GBK character set (possible charset conversion)
根據(jù)上面的信息我們得知目標(biāo)數(shù)據(jù)庫使用的是zhs16gbk字符集,所以:
C:\>set nls_lang=simplified chinese_china.zhs16gbk
C:\>exp scott/tiger file=e:\dept_emp.dmp tables=dept,emp
連接到: Personal Oracle Database 10g Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options
已導(dǎo)出 ZHS16GBK 字符集和 AL16UTF16 NCHAR 字符集
即將導(dǎo)出指定的表通過常規(guī)路徑...
. . 正在導(dǎo)出表 DEPT導(dǎo)出了 4 行
. . 正在導(dǎo)出表 EMP導(dǎo)出了 14 行
成功終止導(dǎo)出, 沒有出現(xiàn)警告。
下面進(jìn)行導(dǎo)入:
C:\>echo %nls_lang%
simplified chinese_china.zhs16gbk
C:\>imp test/tiger file=E:\dept_emp.dmp fromuser=scott touser=test tables=dept,emp
經(jīng)由常規(guī)路徑由 EXPORT:V10.02.01 創(chuàng)建的導(dǎo)出文件
警告: 這些對(duì)象由 SCOTT 導(dǎo)出, 而不是當(dāng)前用戶
已經(jīng)完成 ZHS16GBK 字符集和 AL16UTF16 NCHAR 字符集中的導(dǎo)入
. 正在將 SCOTT 的對(duì)象導(dǎo)入到 TEST
. . 正在導(dǎo)入表 "DEPT"導(dǎo)入了 4 行
. . 正在導(dǎo)入表 "EMP"導(dǎo)入了 14 行
即將啟用約束條件...
成功終止導(dǎo)入, 沒有出現(xiàn)警告。
不同字符集的轉(zhuǎn)換方式:
test@orcl>create table test(x int,y varchar2(10));
test@orcl>insert into test values(1,'張玉');
test@orcl>insert into test values(2,'李明');
Commit;
C:\>set nls_lang=american_america.us7ascii
C:\>exp test/tiger file=e:\test.dmp tables=test
Export done in US7ASCII character set and AL16UTF16 NCHAR character set
server uses ZHS16GBK character set (possible charset conversion)
導(dǎo)出時(shí)發(fā)生了轉(zhuǎn)換
C:\>imp scott/tiger file=e:\test.dmp fromuser=test touser=scott tables=test
import done in US7ASCII character set and AL16UTF16 NCHAR character set
import server uses ZHS16GBK character set (possible charset conversion)
兩次發(fā)生轉(zhuǎn)換。
看看導(dǎo)入后效果:
scott@orcl>select * from test;
X Y
---------- ----------
1 張玉
2 李明
5)識(shí)別導(dǎo)出文件的字符集:
scott@orcl>select nls_charset_id('zhs16gbk') from dual;
NLS_CHARSET_ID('ZHS16GBK')
--------------------------
852
scott@orcl>select nls_charset_name(852) from dual;
NLS_CHAR
--------
ZHS16GBK
sys@orcl>select to_char('1244','xxxx') from dual;
TO_CH
-----
4dc
十進(jìn)制轉(zhuǎn)換為十六進(jìn)制(十六進(jìn)制一般以0x開頭)。
查詢系統(tǒng)有效字符集:
Select nls_charset_id(value) char_id,to_char(nls_charset_id(value),'xxxx'),value from v$nls_valid_values where parameter='CHARACTERSET' and ISDEPRECATED='FALSE';
其實(shí)在進(jìn)行導(dǎo)入導(dǎo)出時(shí),我們要考慮的莫非就是以下四種環(huán)境的字符集:
l Imp 環(huán)境下nls_lang的設(shè)置
l Exp 環(huán)境下 nls_lang的設(shè)置
l S_server(源數(shù)據(jù)庫字符集)
l O_server(目標(biāo)數(shù)據(jù)庫字符集)
另外我們還可以利用UEStudio(UE)編輯器來進(jìn)行相應(yīng)的查看:
用UE打開剛才的test.dmp導(dǎo)出文件,查看第2,3字節(jié)內(nèi)容
上面是00 01
sys@orcl>select nls_charset_name(1) from dual;
NLS_CHAR
--------
US7ASCII
正是us7ascii
當(dāng)然如果你想改變字符集,比如將字符集改成zhs16gbk,只要將上面的前2,3字節(jié)改成相應(yīng)的字符id就行了:
sys@orcl>select nls_charset_id('zhs16gbk') from dual;
NLS_CHARSET_ID('ZHS16GBK')
--------------------------
852
還要注意UE是顯示16進(jìn)制數(shù)的,所以轉(zhuǎn)換成以下:
Select to_char('852','xxxx') from dual;
TO_CH
-----
354
6)使用oracle提供的字符集掃描工具--CSSCAN(character set scan)
這個(gè)工具是掃描數(shù)據(jù)庫并找出所有不兼容的字符,然后通過編寫相應(yīng)的腳本及代碼,轉(zhuǎn)換之后進(jìn)行更新,確保數(shù)據(jù)的正確性。
范例:
使用前必須創(chuàng)建相應(yīng)數(shù)據(jù)字典對(duì)象,利用csminst.sql腳本創(chuàng)建:
sys@orcl>@F:\oracle\product\10.2.0\db_1\RDBMS\ADMIN\csminst.sql
這個(gè)腳本創(chuàng)建相應(yīng)用戶(csmig)及數(shù)據(jù)字典對(duì)象,掃描信息會(huì)記錄在相應(yīng)的數(shù)據(jù)字典表里。
C:\>csscan full=y fromchar=zhs16gbk tochar=us7ascii log=E:\us7check.log capture=
y array=1000000 process=2
Username: system
Password:
不能轉(zhuǎn)換的數(shù)據(jù)將會(huì)被記錄下來,可以在這些信息轉(zhuǎn)換之后,對(duì)數(shù)據(jù)進(jìn)行相應(yīng)的更新,確保轉(zhuǎn)換無誤。
聯(lián)系客服