UTF8

zhouwf0726發表於2019-02-20

utf8 全包容了gbk ,並沒有超集和子集的關係;
8i 的資料庫 的 utf8 是 4位定長的字元編碼;
9i 和以上資料庫的utf8 有4位定長AL32UTF8和 不定長的 UTF8 ,都是unicode編碼;
其中,utf8 編碼中字元大多是三位元組的編碼,一個漢字是 3位元組的編碼;
zhs16gbk 並不是unicode 編碼,只是提供了對gbk漢字編碼的支援, 一個漢字為雙位元組;
utf8 對於 zhs16gbk 中的所有編碼都有唯一的編碼以之對應,所以我說utf8 全包容了gbk;
當然,utf8作為一種unicode 編碼,他還提供 global character 的支援;
假如設定得當,從 zhs16gbk 到utf8 是可以實現無損耗的字元轉換的;

////


SQL> create table t(id varchar2(10));

表已建立。

SQL> insert into t values('aaaaaaaaaa');

已建立 1 行。

SQL> insert into t values('aaaaaaaaaaa');
insert into t values('aaaaaaaaaaa')
*
第 1 行出現錯誤:
ORA-12899: value too large for column "ZWF"."T"."ID" (actual: 11, maximum: 10)


SQL> insert into t values('中國');

已建立 1 行。

SQL> insert into t values('中國中國');
insert into t values('中國中國')
*
第 1 行出現錯誤:
ORA-12899: value too large for column "ZWF"."T"."ID" (actual: 12, maximum: 10)


SQL> insert into t values('中國中');

已建立 1 行。

SQL> COL DMP FORMAT A30

SQL> SELECT ID,DUMP(ID) DMP,ASCII(ID) FROM T;

ID DMP ASCII(ID)
---------- ------------------------------ ----------
aaaaaaaaaa Typ=1 Len=10: 97,97,97,97,97,9 97
7,97,97,97,97

中國 Typ=1 Len=6: 228,184,173,229,1 14989485
55,189

中國中 Typ=1 Len=9: 228,184,173,229,1 14989485
55,189,228,184,173

SQL> COL PARAMETER FOR A20
SQL> COL VALUE FOR A20

SQL> SELECT * FROM NLS_DATABASE_PARAMETERS;

PARAMETER VALUE
--------------- --------------------
NLS_LANGUAGE AMERICAN
NLS_TERRITORY AMERICA
NLS_CURRENCY $
NLS_ISO_CURRENC AMERICA
Y

NLS_NUMERIC_CHA .,
RACTERS

NLS_CHARACTERSE UTF8 --目前我們的設定
T

PARAMETER VALUE
--------------- --------------------

NLS_CALENDAR GREGORIAN
NLS_DATE_FORMAT DD-MON-RR
NLS_DATE_LANGUA AMERICAN
GE

NLS_SORT BINARY
NLS_TIME_FORMAT HH.MI.SSXFF AM
NLS_TIMESTAMP_F DD-MON-RR HH.MI.SSXF
ORMAT F AM


PARAMETER VALUE
--------------- --------------------
NLS_TIME_TZ_FOR HH.MI.SSXFF AM TZR
MAT

NLS_TIMESTAMP_T DD-MON-RR HH.MI.SSXF
Z_FORMAT F AM TZR

NLS_DUAL_CURREN $
CY

NLS_COMP BINARY
NLS_LENGTH_SEMA BYTE

PARAMETER VALUE
--------------- --------------------
NTICS

NLS_NCHAR_CONV_ FALSE
EXCP

NLS_NCHAR_CHARA AL16UTF16
CTERSET

NLS_RDBMS_VERSI 10.1.0.4.0
ON


已選擇20行。

字符集掃描工具(zt):

一、the Character Set Scanner Utility的作用  分析字元資料轉換到新的字符集的可行性和可能存在的問題並給出一個評估報告,使用者可依據該報告確定如何進行字符集轉換。
  該工具主要測試在轉換到新的字符集時資料的字元編碼會作什麼改變;是否能成功轉換到新的字符集;轉換後的資料是否適合當前列的大小。只檢測CHAR, VARCHAR2, LONG, CLOB, NCHAR, NVARCHAR2, and NCLOB資料型別的列,不測試LONG, CLOB, and NCLOB資料型別的大小。
  
  二、工具的準備
  在使用前必須執行一個SQL指令碼CSMINST.SQL,該指令碼位於$Oracle_home/rdbms/admin,只須執行一次,主要用於建立與掃描相關的一些資源。
  cd
  sqlplus system/manager
  SQL> start csminst.sql
  
  三、工具的執行
  執行掃描的使用者必須具備DBA許可權。在命令列下執行Csscan,有三種執行方式:
  1、使用引數檔案 csscan system/manager PARFILE=filename
  2、命令列直接給出引數 csscan system/manager full=y tochar=zhs16gbk array=10240 process=3
  3、使用互動模式 csscan system/manager
  
  四、引數說明
  要獲得使用幫助在命令列下輸入 csscan help=y
  ARRAY:定義用於提取資料的buffer大小,該值決定掃描時每次讀取資料的行數,因此影響掃描時間的長短;如果char和varchar2列的大小之和大於該值,則每次讀取一行資料;如果包含LONG, CLOB, or NCLOB列則每次也只讀取一行。
  預設值:10240;最小值:4096;最大值:無限。
  BOUNDARIES:用於在生成應用資料包告時按列大小分組報告的分界值,例如設該值為(10,50,100),則在生成的評估報告中應用資料按char(1..10),char(11..50),char(51..100)分組列出,VARCHAR2, NCHAR, and NVARCHAR2 資料型別一樣。
  CAPTURE:確定是否獲取可轉換行的資訊到表CSM$ERRORS,主要用於選擇資料eXPort/import到目標字符集。
  取值範圍:Y or N ,預設值:N。
  FEEDBACK:定義顯示掃描進度的每個點代表已掃描多少行。
  預設值:無;最小值:100;最大值:100000 。
  FROMCHAR:說明資料庫CHAR, VARCHAR2, LONG, CLOB資料型別的實際字符集,預設使用資料庫的字符集。
  FROMNCHAR:說明資料庫NCHAR, NVARCHAR2, NCLOB資料型別的實際國家字符集,預設使用資料庫的國家字符集。
  FULL:是否執行全資料庫掃描,如果是則掃描整個資料庫包括資料字典。
  取值範圍:Y or N ,預設值:N。
  HELP:顯示關於所有引數的幫助資訊。
  取值範圍:Y or N ,預設值:N。
  LASTRPT:指示是否產生基於上一次掃描的統計資訊上的掃描報告。
  取值範圍:Y or N ,預設值:N。
  LOG:產生報告的檔名,預設為scan;
  有三個檔案:掃描彙總報告scan.txt,獨立的例外報告scan.err,掃描日誌檔案scan.out。
  MAXBLOCKS:定義每個表的最大塊的大小,以便大表能分成小塊給某個掃描程式。
  預設值:無;最小值:1000;最大值:無限。
  PARFILE:指定引數檔案。
  PROCESS:定義併發掃描程式數。
  預設值:1;最小值:1;最大值:32。
  SUPPRESS:定義每個表的最大例外數,掃描記錄例外資訊到表CSM$ERRORS中,該引數限制記錄每個表最大的例外數。
  預設值:無限;最小值:0;最大值:無限。
  TABLE:指定掃描特定的表。
  TOCHAR:指定需要轉換的目標字符集。
  TONCHAR:指定需要轉換的目標國家字符集,如果未指定將不掃描NCHAR, NVARCHAR2, NCLOB資料型別的資料 。
  USER:指定要掃描的表的擁有者,如果未指定TABLE引數,則掃描該使用者所有表。
  USERID:執行掃描的使用者名稱和密碼(如不在本地還需要加上連線字串),未輸密碼,系統將會提示你輸入。
  
  五、掃描結果
  掃描將產生兩個結果報告:彙總報告和例外報告,彙總報告檔案字尾為.txt,例外報告檔案字尾為.err。
  彙總報告包括資料庫大小(每個表空間的大小和使用情況)、掃描引數、掃描總結、資料字典轉換總結、應用資料轉換總結、應用資料轉換按列大小總結、每張表可轉換資料分佈、每個列可轉換資料分佈、重建的索引。
  掃描總結依掃描模式可包含兩個內容:資料字典和應用資料;他們又分別有三種情況:所有資料保持不變、所有資料可以轉換、一些資料不可轉換。
  資料字典轉換總結和應用資料轉換總結分別對相應資料的可轉換情況按資料型別統計數量,其也分為三種情況:保持不變、可轉換、例外(不可轉換)。
  應用資料轉換按列大小總結同上,只是依據BOUNDARIES引數按列大小統計。
  每張表可轉換資料分佈和每個列可轉換資料分佈分別按表和按列統計可轉換資料和例外資料的分佈數量。
  重建的索引列出在import時能夠重建的索引。
  例外報告包括掃描引數和應用資料例外。
  應用資料例外列出所有例外資料(不能被轉換),以便這些資料在必要時進行修改。有兩種型別的例外:大小超出和損失轉換;大小超出指的是資料轉換為新的字符集後會比原來的字元寬;損失轉換的這些資料需在轉換前被修正合適新字符集或將被轉換為亂碼。

字符集相關問題(zt):

在國內外大中型資料庫管理系統中,把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
  parameter value
  NLS_LANGUAGE AMERICAN
  NLS_TERRITORY AMERICA
  …. ….
  NLS_CHARACTERSET US7ASCII
  NLS_SORT BINARY
  NLS_NCHAR_CHARACTERSET US7ASCII
  
  從上述列表資訊中可看出伺服器端ORACLE資料庫的字符集為'US7ASCII'。
  
  (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資料庫字符集已復原,這時再檢視有漢字字元資料的表時,漢字已能被正確顯示。
  
  (3)利用資料格式轉儲,避開字符集限制
  這種方法主要用於載入外來ORACLE資料庫的不同字符集資料。其方法如下:
  
  先將資料載入到具有相同字符集的伺服器上,然後用轉換工具卸出為foxbase 格式或access格式資料庫,再用轉換工具轉入到不同字符集的ORACLE資料庫中,這樣就避免了ORACLE字符集的困擾。目前資料庫格式轉換的工具很多,象power builder5.0以上版本提供的pipeline,Microsoft Access資料庫提供的資料匯入/匯出功能等。轉換方法參見有關資料說明。.
  
  2.3匹配字符集替換漢字
  
  對於1.3提到的情況,沒有很好的辦法,只能先把客戶端與伺服器端字符集匹配一致後,根據原輸入漢字的特徵碼替換漢字字元部分。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/756652/viewspace-242458/,如需轉載,請註明出處,否則將追究法律責任。

相關文章