[轉]sqlldr 導入亂碼,Oracle客戶端字符集問題

 1,查Oracle數據庫建立時候的字符集:
oracle服務器端執行

SQL> select name, value$ from sys.props$ where name like 'NLS%';

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

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

20 rows selected.

確認數據庫建立的時候選擇的字符集是 UTF-8
.執行sql :select userenv('language') from dual; 獲取oracle服務端字符集X

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

USERENV('LANGUAGE')
----------------------------------------------------
SIMPLIFIED CHINESE_CHINA.UTF8


2.  檢查執行 sqlldr 的客戶端的 NLS_LANG 的設置
Oracle 客戶端執行

[oracle@localhost hx]$ echo $NLS_LANG
AMERICAN_AMERICA.UTF8


3. 儘可能讓以上3個步驟檢查出的字符集設置都一致,開始經過 sqlldr 導入文本,並檢查結果。


一般出現問題的緣由,可分爲三種: 

1. 服務器指定字符集與客戶字符集不一樣,而與加載數據字符集一致。 

解決方法:對於這種狀況,只須要設置客戶端字符集與服務器端字符集一致就能夠了

oracle10g UTF8編碼:AMERICAN_AMERICA.AL32UTF8mysql

      GBK編碼:SIMPLIFIED CHINESE_CHINA.ZHS16GBKlinux

客戶端修改成中文是:在linux的終端上設置環境變量
1.LANG=zh_CN
2.NLS_LANG=zhs16gbk

2. 服務器指定字符集與客戶字符集相同,與加載數據字符集不一致。 

解決方法:強制加載數據字符集與服務器端字符集一致。

3. 服務器指定字符集與客戶字符集不一樣,與輸入數據字符集不一致。 

對於這種狀況,目前爲止都尚未太好的解決方法。 

其中有的時候能夠嘗試經過iconv -f utf-8 -t gbk filename
從原字符集 utf-8 轉換成 gbk 


修改數據庫端字符集的方法:
  1.服務器端字符集的設置和修改:
1.1 建立數據庫的時候直接選擇正確的字符集(顯示漢字的字符集主要有ZHS16CGB231280,US7ASCII,WE8ISO8859P1,ZHS16GBK等)
1.2若是建立的時候沒有選擇字符集,那麼字符集將使用默認的字符集.可使用以下命令查看數據庫的字符集.用oracle的合法用戶登陸.select * from V$NLS_PARAMETERS.
SQL > select * from V$NLS_PARAMETERS
parameter value
NLS_LANGUAGE AMERICAN
NLS_TERRITORY AMERICA
…. ….
NLS_CHARACTERSET WE8ISO8859P1
NLS_SORT BINARY
NLS_NCHAR_CHARACTERSET WE8ISO8859P1
---- 從上述信息看出ORACLE 數據庫的字符集爲' WE8ISO8859P1'。
能夠用update 命令修改數據庫的字符集,可是注意:修改字符集可能會對原有數據形成破壞,修改以前必定要先備份數據庫.命令以下:
用戶sys 以sysdba的身份登陸oracle. 字串9 
SQL>update props$ set value$=’ZHS16GBK’ where name=’NLS_CHARACTERSET’
若是客戶端的字符集和服務器端不相同,就必須修改字符集.不然不能正確的顯示漢字.通常建議修改客戶端的字符集.
1.3不一樣字符集數據庫之間的數據導入
a)從新安裝數據庫或者是用update命令修改字符集。
b)強行修改oracle數據庫當前字符集。以sysdba的身份登陸oracle
SQL > create database character set ZHS16GBK (注:這裏的字符集爲導出數據的字符集)
* create database character set ZHS16GBK
ERROR at line 1:
ORA-01031: insufficient privileges
不用理會這個錯誤,用imp 裝入數據。數據裝完後,重啓動oracle 數據,select * from V$NLS_PARAMETERS 此時,你會發現,數據庫字符集又回到原來的字符集。
c)用第三方工具繞開字符集。如powerbuild的pipeline,delphi的datadump,MS access的數據導入導出工具。

sql

客戶端字符集

一、 客戶端字符集含義
客戶端字符集定義了客戶端字符數據的編碼方式,任何發自或發往客戶端的字符數據均使用客戶端定義的字符集編碼,客戶端能夠看做是能與數據庫直接鏈接的各類應用,例如sqlplus,exp/imp等。客戶端字符集是經過設置NLS_LANG參數來設定的。

二、NLS_LANG 參數格式
NLS_LANG= Language_ Territory. Client character se
Language: 顯示oracle消息、校驗、日期命名
Territory :指定默認日期、數字、貨幣等格式
Client character set :指定客戶端將使用的字符集
例如: NLS_LANG=AMERICAN_AMERICA.US7ASCII
AMERICAN是語言,AMERICA是地區,US7ASCII是客戶端字符集
三、 客戶端字符集設置方法
1)UNIX 環境
$NLS_LANG=「simplified chinese」_china.zhs16gbk
$export NLS_LANG
編輯oracle用戶的.profile文件(或.bash_profile linux)
$ export NLS_LANG="SIMPLIFIED CHINESE"_CHINA.UTF8
2)Windows 環境
編輯註冊表
Regedit.exe   HKEY_LOCAL_MACHINE---SOFTWARE---ORACLE—HOME0

在DOS名下執行:

Set NLS_LANG=「simplified chinese」_china.zhs16gbk
四、 NLS 參數查詢
Oracle 提供若干NLS參數定製數據庫和用戶機以適應本地格式,例若有NLS_LANGUAGE,NLS_DATE_FORMAT,NLS_CALENDER等,能夠經過查詢如下數據字典或v$視圖查看。
NLS_DATABASE_PARAMETERS-- 顯示數據庫當前NLS參數取值,包括數據庫字符集取值
NLS_SESSION_PARAMETERS--  顯示由NLS_LANG 設置的參數,或通過alter session 改變後的參數值(不包括由NLS_LANG 設置的客戶端字符集)
NLS_INSTANCE_PARAMETE-- 顯示由參數文件init.ora 定義的參數V$NLS_PARAMETERS--顯示數據庫當前NLS參數取值 數據庫

圖1-3 查詢NLS參數值bash

五、 修改NLS參數
使用下列方法能夠修改NLS參數
(1)修改實例啓動時使用的初始化參數文件
(2)修改環境變量 NLS_LANG
(3)使用ALTER SESSION語句,在oracle會話中修改
(4)使用某些SQL函數
NLS 做用優先級別:Sql function>alter session>環境變量或註冊表>參數文件>數據庫默認SQL*Loader的字符集轉換

使用SQL*Loader向數據庫裝載數據,有兩種轉換字符集的模式

常規路徑: 數據被轉換爲 NLS_LANG 指定的會話字符集或者控制文件指定的字符集。

控制文件能夠指定字符集

SQL*Loader control file:

LOAD DATA

CHARACTERSET UTF16

INFILE ulcase11.dat

REPLACE …

若是數據文件的字符集與NLS_LANG環境變量的字符集不一致,SQL*Loader以NLS_LANG指定的字符集編碼存入數據庫。

直接路徑: 數據使用客戶端指示被轉換.

這樣要求數據庫的字符集是數據文件字符集的超級,不然有可能出現亂碼。

亂碼問題及解決辦法

要在客戶端正確顯示ORACLE數據庫中的漢字信息,首先必須使客戶端的字符集與服務器端的字符集一致;其次是加載到ORACLE數據庫的數據字符集必須與服務器字符集一致。據此,漢字顯示亂碼的問題大體能夠分爲如下幾種狀況:
一、客戶端字符集與服務器端字符集不一樣,服務器端字符集與加載數據字符集一致。

如:

以system用戶登陸,建立表,插入數據。服務器

圖1-4 亂碼問題-正確的客戶端字符集session

圖1-5 亂碼問題-不一致的客戶端字符集oracle

這種狀況是最多見的,只要把客戶端的字符集設置正確便可。具體解決方案:
第一步:查詢V$NLS_DATABASE_PARAMETERS獲得服務端的字符集:
SQL>SELECT * FROM V$NLS_DATABASE_PARAMETERS WHERE PARAMETER=’ NLS_CHARACTERSET;
PARAMETER VALUE
-----------------------------------------------------
NLS_CHARACTERSET ZHS16GBK

第二步:根據服務端的字符集設定客戶端的字符集,設定方法參見客戶端的字符集的設定方式。以LINUX系統爲例,可在當前用戶的.bash_profile文件中增長以下兩行:
NLS_LANG=SIMPLIFIED Chinese_CHINA.ZHS16GBK
export NLS_LANG
二、客戶端字符集與服務器端字符集相同,服務器端字符集與加載數據字符集不一致。這種狀況通常發生在ORACLE版本升級或從新安裝數據庫時選擇了與原來數據庫不一樣的字符集,而恢復加載的備份數據還是按原字符集卸出的場合。另外一種狀況是加載從其它使用不一樣字符集的ORACLE數據庫卸出的數據。在這兩種狀況中,無論客戶端字符集與服務器端字符集是否一致都沒法正確顯示漢字。如:

具體解決方案:
方案一:按服務端字符集的修改方法修改服務端字符集與加載數據字符集一致,而後導入數據。
方案二:利用數據格式轉儲,避開字符集帶來的問題。即先將加載數據倒入到與其字符集一致的數據庫中,而後再將數據要麼按文本格式導出(數據量較小的狀況下),要麼經過第三方工具(如POWER BUILDER,ACCESS,FOXPRO等)倒出數據,最後將倒出的數據導入到目標數據庫中。
三、客戶端字符集與服務器端字符集不一樣,服務端字符集與輸入數據字符集不一樣。這種狀況是在客戶端字符集與服務器端字符集不一致時,從客戶端輸入了漢字信息。輸入的這些信息即使是把客戶端字符集更改正確,也沒法顯示漢字。

如:函數

圖1-6 亂碼問題—錯誤的客戶端字符集工具

圖1-7 亂碼問題—正確的客戶端字符集

 

解決方案:修改客戶端字符集與服務端字符集一致後,從新輸入數據。 

相關文章
相關標籤/搜索