對於Oracle數據庫之間的移植采用Oracle的導入導出工具(Import/Export)是一個比較好的策略。雖也可以利用第三方軟件如Sybase 的Power designer中的Reverse Engineering 進行數據庫結構重建,然後在進行較復雜的數據導入過程,但對於作業隊列、快照等則不得不用手工來創建。而Export能將整個數據庫、指定用戶、指定表和相關的數據字典進行輸出,Export輸出的輸出轉存二進制文件包括了完全重建所有被選對象所需的命令。
本人在為某電廠MIS(Oracle數據庫)數據采用Oracle的導入導出工具從Windows NT平台移植到Digital Unix平台時遇到的關於字符集的問題和總結出的經驗與大家來分享。
1. 移植環境
原操作系統平台: Windows NT
數據庫: Oracle 8.0.5 for Windows NT
服務器:HP NetServer LH3
目標操作系統平台:Digital Unix alpha V4.0
數據庫:Oracle 8.0.4 for Digital Unix
服務器:ALPHASERVER ES40 小型機
2. 數據導出
在NT服務器上用Oracle導出工具進行數據導出,Oracle導出工具有命令行和圖形界面兩種方式。
本人直接用命令行方式進行數據導出:
c:> exp80 gxmisdba/manager file=c:expdat.dmp log=c:export.log
即將導出指定的用戶...
. 正在導出用戶GXMISDBA的外部函數程序庫名稱
. 正在導出用戶GXMISDBA的對象類型定義
即將導出GXMISDBA的對象 ...
. 正在導出數據庫鏈接
. 正在導出序號
. 正在導出群集定義
. 即將導出GXMISDBA的表通過常規路徑 ...
. . 正在導出表 AAAAA 0 行被導出
. . 正在導出表 EVT_CARRIER_CONFIGURATION 0 行被導出
. . 正在導出表 TBL_AJ_AGKS 331 行被導出
.
.
.
. 正在導出同義詞
. 正在導出視圖
. 正在導出存儲的過程
. 正在導出參考資料一致性約束條件
. 正在導出觸發器
. 正在導出後期表活動
. 正在導出快照
. 正在導出快照日志
. 正在導出作業隊列
. 正在導出刷新組和子組
在沒有警告的情況下成功終止導出。
3.數據導入
在NT服務器上通過FTP命令將導出的輸出轉存二進制文件expdat.dmp(使用binary傳輸模式)傳輸至Digital Unix服務器上。
用Oracle for Digital Unix 數據導入工具命令行方式進行數據導入
$imp gxmisdba/manager file=/expdat.dmp full=y log=u01import.log
Connected to: Oracle8 Enterprise Edition Release 8.0.4.0.0 - Production
PL/SQL Release 8.0.4.0.0 - Production
Export file created by EXPORT:V08.00.05 via conventional path
. importing GXMISDBAs objects into GXMISDBA
. . importing table "AAAAA" 0 rows imported
. . importing table "EVT_CARRIER_CONFIGURATION" 0 rows imported
. . im
porting table "TBL_AJ_STK" 331 rows imported
IMP-00017: following statement failed with Oracle error 2437:
"ALTER TABLE "TBL_KJ_JLRY" ADD CONSTRAINT "PK_TBL_KJ_JLRY" PRIMARY KEY ("FLD_KJ_JLRY_BH","FLD_KJ_JLRY_XM") USING INDEX PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE (INITIAL 10240 NEXT 10240 MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 50 FREELISTS 1 FREELIST GROUPS 1 BUFFER_POOL DEFAULT)"
" ENABLE NOVALIDATE"
IMP-00003: Oracle error 2437 encountered
ORA-02437: cannot enable (GXMISDBA.PK_TBL_KJ_JLRY) - primary key violated
.
.
.
Import terminated successfully with warnings.
數據導入出現20多個以上類似錯誤,後分析其中報錯的"TBL_AJ_STK"表,發現"FLD_KJ_JLRY_XM"字段值(關鍵字組成之一)為中文字符而在Digital Unix服務器Oracle數據庫中"FLD_KJ_JLRY_XM"字段值顯示的為"????"(在客戶端用Oracle Sql Plus查看),從而造成關鍵字沖突。
在客戶端Oracle Sql Plus對某行顯示"????"的字段值進行修改,如改成中文值”測試”,提交後,用SQL語句查看,剛修改的行中顯示"????"的字段值變成了”測試”,這說明了Digital UNIN服務器上的Oracle數據集可以存儲中文字符,但Oracle 8.0.4 for Digital UNIN的導入工具imp未能將Oracle 8.0.5 for Windows NT imp80導出的中文數據進行轉換。
4.查看字符集參數
4.1查看Oracle 8.0.5 for Windows NT props$內容
SQL> connect sys/change_on_install
SQL> col value$ format a40
SQL> select name,value$ from props$;
NAME VALUE$
---------------------------------------
DICT.BASE 2
NLS_LANGUAGE AMERICAN
NLS_TERRITORY AMERICA
NLS_CURRENCY $
NLS_ISO_CURRENCY AMERICA
NLS_NUMERIC_CHARACTERS .,
NLS_CALENDAR GREGORIAN
NLS_DATE_FORMAT DD-MON-YY
NLS_DATE_LANGUAGE AMERICAN
NLS_CHARACTERSET ZHS16GBK
NLS_SORT BINARY
NLS_NCHAR_CHARACTERSET ZHS16GBK
NLS_RDBMS_VERSION 8.0.5.0.0
GLOBAL_DB_NAME Oracle.WORLD
EXPORT_VIEWS_VERSION 7
已選擇15行。
4.2查看Oracle 8.0.4 for Digital UNIN 的props$內容
SQL> connect sys/change_on_install
SQL> col value$ format a40
SQL> select name,value$ from props$;
NAME VALUE$
---------------------------------------
DICT.BASE 2
NLS_LANGUAGE AMERICAN
NLS_TERRITORY AMERICA
NLS_CURRENCY $
NLS_ISO_CURRENCY AMERICA
NLS_NUMERIC_CHARACTERS .,
NLS_CALENDAR GREGORIAN
NLS_DATE_FORMAT DD-MON-YY
NLS_DATE_LANGUAGE AMERICAN
NLS_CHARACTERSET ZHS16CGB231280
NLS_SORT BINARY
NLS_NCHAR_CHARACTERSET ZHS16CGB231280
NLS_RDBMS_VERSION 8.0.4.0.0
GLOBAL_DB_NAME ORCL.WORLD
EXPORT_VIEWS_VERSION 7
15 rows selected.
發現Oracle 8.0.4 for Digital UNIN 采用了Oracle在Digital Unix環境下建議的中文字符集ZHS16CGB231280,兩者的字符集不同,於是本人就在Digital UNIN服務器上重新安裝Oracle,選擇了與NT上同樣的字符集ZHS16GBK(中國簡體漢字16位國標庫)。安裝完成後,通過查看props$的內容,確認了Oracle 8.0.4 for Digital UNIN和Oracle 8.0.5 for Windows NT的字符集一致。於是用Oracle 8.0.4 for Digital UNIN的導入工具imp重新進行數據導入,但還是報同樣的錯誤,問題還未得到解決。
5.問題解決辦法
後來本人發現在Oracle 8.0.5 for Windows NT的服務器(或裝有Oracle 8.0.5 for windows 95/98的工作站)上直接用Oracle 8.0.5 for Windows NT的導入工具imp80遠程對Oracle 8.0.4 for Digital UNIN數據庫進行數據導入,問題竟得到解決。
5.1在NT的服務器上,修改tnsnames.ora(或通過Oracle Net8 Easy config)設置數據庫連接字符串gxmis(可自行設定)指向Oracle 8.0.4 for Digital UNIN服務器。
5.2在NT的服務器上進行數據遠程導入
c:>imp80 file=c:expdat.dmpfull=y log=c:import.log
已連接到:Oracle8 Enterprise Edition Release 8.0.4.0.0 - Production
PL/SQL Release 8.0.4.0.0 - Production
經由常規路徑導出由EXPORT:V08.00.05創建的文件
. 正在將GXMISDBA的對象導入到 GXMISDBA
. . 正在導入表 "AAAAA" 0行被導入
. . 正在導入表 "EVT_CARRIER_CONFIGURATION" 0行被導入
. . 正在導入表 "TBL_AJ_AGKS" 331行被導入
.
.
.
准備啟用約束條件...
成功終止導入
5.3把Oracle 8.0.4 for Digital U
NIN字符集重新又改成ZHS16CGB231280,進行數據遠程導入測試,數據也同樣地導入成功。說明ZHS16CGB231280字符集可以兼容ZHS16GBK字符集。6.經驗總結
6.1在Oracle 8.0.4 for Digital UNIN服務器上(字符集ZHS16GBK)用8.0.4 for Digital UNIN的導出工具exp將已正常(即可存儲和顯示中文)的數據庫導出。
$ exp gxmisdba/manager file=/u01/expdat.dmp log=/u01/export.log
顯示成功導出。
在用Oracle 8.0.4 for Digital UNIN的導入工具imp進行導入
$imp gxmisdba/manager file=/u01/expdat.dmp full=y log=u01import.log
錯誤又重現。
6.2在NT服務器上通過FTP命令將在Oracle 8.0.4 for Digital UNIN服務器上剛導出的輸出轉存二進制文件expdat.dmp下載至NT服務器上,用imp80進行遠程導入。
c:>imp80 file=c:expdat.dmp full=y log=c:import.log
已連接到:Oracle8 Enterprise Edition Release 8.0.4.0.0 – Production
PL/SQL Release 8.0.4.0.0 – Production
IMP-00016: 不支持要求的字符集轉換(從類型1到852)
IMP-00000: 未成功終止導入
6.3在NT服務器上對Digital UNIN服務器上的數據進行遠程導出(備份)
c:>exp80 file=c:expdat.dmp full=y log=c:import.log
顯示成功導入。通過客戶端Oracle Sql Plus查看中文顯示正常。
從而說明在Oracle 8.0.4 for Digital UNIN服務器上對含有中文的數據庫的數據移植、備份、數據恢復不要用Oracle 8.0.4 for Digital UNIN本身自帶的導入導出工具imp,exp,應使用能進行中文導入導出的工具,如imp80,exp80。