iT邦幫忙

DAY 18
2

哇咧~夠了(Oracle SQL)系列 第 15

十八、Unicode vs Big5(Oracle SQL 2013/10/03)

  • 分享至 

  • xImage
  •  

Oracle 11g (EBS R12)之後,中文字定義有些改變,從以前認知的雙位元組Big5,
改為支援Unicode,而且每個中文字變成3位元組。
從下列函數結果可以看出差異
select lengthb('1國2制') lb, length('1國2制') ll
from dual

英數字=1*2 = 2
中文字=3*2 = 6
所以

lengthb('1國2制')=8
length('1國2制')=4,因為單純只考慮字(不管半形全形都算是1)
LB LL


8 4

所以透過這個特性,可以算出這個欄位值裡面有幾個中文字

select '1國2制' "這裡面"
, (lengthb('1國2制') - length('1國2制')) / 2 "中文字數"
from dual

這裡面 中文字數


1國2制 2

而且,這個改變,導致我上一篇產生不了作用,除非用的還是Oracle 10g以前的DB。
select chr(162)||chr(185) from dual;羅馬字I

比對幾個字,我發現,變化關系其實應該是很單純,只是因為Oracle自己已經出了處理函數,就不多敘述了
Big5
一 乙 丁 七
A440,A441,A442,A443

Unicode,
一 丁 丂 七
4E00,4E01,4E02,4E03

這裡有介紹這個案例: 詳細可自行參閱原文
< http://www.sqlsnippets.com/en/topic-13406.html >

select 
 'Arabic     : ' || unistr( '\0627\0644\0639\0631\0628\064A\0629' )      || '
  Chinese    : ' || unistr( '\4E2D\6587' )                               || '
  English    : ' || unistr( 'English' )                                  || '
  French     : ' || unistr( 'Fran\00E7ais' )                             || '
  German     : ' || unistr( 'Deutsch' )                                  || '
  Greek      : ' || unistr( '\0395\03BB\03BB\03B7\03BD\03B9\03BA\03AC' ) || '
  Hebrew     : ' || unistr( '\05E2\05D1\05E8\05D9\05EA' )                || '
  Japanese   : ' || unistr( '\65E5\672C\8A9E' )                          || '
  Korean     : ' || unistr( '\D55C\AD6D\C5B4' )                          || '
  Portuguese : ' || unistr( 'Portugu\00EAs' )                            || '
  Russian    : ' || unistr( '\0420\0443\0441\0441\043A\0438\0439' )      || '
  Spanish    : ' || unistr( 'Espa\00F1ol' )                              || '
  Thai       : ' || unistr( '\0E44\0E17\0E22' )
  as unicode_test_string
from dual ;

當然維基百科,也是要補上來湊個熱鬧。
http://zh.wikipedia.org/wiki/Unicode%E8%A3%9C%E5%AE%8C%E8%A8%88%E7%95%AB

那就用這個unistr案例來說明
Ⅰ~Ⅸ \2160 ~ \2168

  1  select rownum "N"
  2  ,  '\'|| trim(to_char (8544 + rownum - 1, 'XXXX') ) uni_code
  3  ,  unistr('\'|| trim(to_char (8544 + rownum - 1, 'XXXX') )) "unichar"
  4    from all_tables
  5*  where rownum <= 9
SQL> /

         N UNI_CODE     unichar
---------- ------------ ------------
         1 \2160        Ⅰ
         2 \2161        Ⅱ
         3 \2162        Ⅲ
         4 \2163        Ⅳ
         5 \2164        Ⅴ
         6 \2165        Ⅵ
         7 \2166        Ⅶ
         8 \2167        Ⅷ
         9 \2168        Ⅸ

已選取 9 個資料列.

這裡在查文的過程,我發現,
原來to_number(), to_char(),已經可以自由轉換16進位、10進位了!

[開發技術組]全文閱讀
http://ithelp.ithome.com.tw/ironman6/player/yafuu168/dev/1

[鐵人人生組]全文閱讀
http://ithelp.ithome.com.tw/ironman6/player/yafuu168/life/1


上一篇
十七、一定要頑抗嗎?(Oracle SQL 2013/10/02)
下一篇
十九、比較的簡單級,簡單事不要複雜處理(Oracle SQL 2013/10/04)
系列文
哇咧~夠了(Oracle SQL)28
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

1 則留言

0
月半車甫
iT邦研究生 3 級 ‧ 2013-10-05 11:57:26

這個改變,對某些進行資料庫升級的企業,
或許會影響到原客製的結果產生不可預期的錯誤發生?會不會說的晚了?
像是Y2K、民國百年蟲。

我要留言

立即登入留言