KB-在Oracle中直接取得中文字串長度

今天接到個頗具挑戰性的需求。

由於轉檔程式要輸出固定寬度的文字欄位,所以要視字串長度在後方補足空白。因中文字在不同Encoding下的長度不同(例如: BIG5 2bytes, UTF8 3bytes),加上中英文可能交雜,所以用.NET下的System.Text.Encoding.GetEncoding("big5").GetByteCount("中文字串ABC");是最簡便有效的方法(若是VBS、VB6,可以考慮用ADODB.Stream勉強替代)。
不過,問題來了。因為轉檔程式是別人寫好的,改不得,而它只能笨笨地接受從ORACLE資料庫端傳來補好空白的文字內容(這轉檔程式會不會太嬌生慣養呀?)。所以計算文字長度的事情得在ORACLE端搞定,HOW?

如果是SQL Server,我會用Collate處理編碼轉換,用DataLength來取真實資料長度。不過因為ORACLE中沒有直接對應的語法,拼拼湊湊一番,才總算找到解法:

  1. CONVERT Function: 可以將字串轉成不同的Charset
  2. RAWTOHEX Function: 可將欄位內容用16進位表示,所以其長度除2就是原欄位的Byte數!

把這些東西攪在一起,答案就出來了囉~~
(由以下的測試可以看出來,UTF8時,每個中文字要三個Byte,而BIG5只需要兩個)

Update 2007-05-17
網友Nolem提供了一個我不知道的美妙函數--Lenthb,所以用LengthB就可以直接測量資料長度,比起來,原來的轉Hex String再數長度,簡直是脫了褲子、洗完屁股才放屁! 哈! 謝謝Nolem的分享。

歡迎推文分享:
Published 24 November 2006 10:12 AM 由 Jeffrey
Filed under: ,
Views: 28,404



意見

# nolem said on 16 May, 2007 11:46 AM

如果先轉成 single byte char 再倒出文字檔不知是否可行,

create table testchar (ch varchar2(10),nch nvarchar2(10));

insert into testchar values('測試','林堃');

commit;

select NCH ,length(NCH) len ,lengthb(NCH) lenb,length(to_single_byte(NCH)) s_len ,to_single_byte(NCH) s_name from testchar ;

==================

NCH     LEN     LENB     S_LEN     S_NAME    

------  ------  -------  --------  ---------

林?      2       4        2         林?        

我的tool顯示nchar有問題~~所以沒法測試是否ok~~

您要試試看嗎?

# Jeffrey said on 16 May, 2007 08:41 PM

剛才試了一下,Lengthb很管用,比起轉Hex再數長度高明多了,身為Oracle麻瓜的我原本不知道有這個函數可用,謝謝分享!

你的看法呢?

(必要的) 
(必要的) 
(選擇性的)
(必要的) 
(提醒: 因快取機制,您的留言幾分鐘後才會顯示在網站,請耐心稍候)

5 + 3 =

搜尋

Go

<November 2006>
SunMonTueWedThuFriSat
2930311234
567891011
12131415161718
19202122232425
262728293012
3456789
 
RSS
創用 CC 授權條款
【廣告】
twMVC

Tags 分類檢視
關於作者

一個醉心技術又酷愛分享的Coding魔人,十年的IT職場生涯,寫過系統、管過專案, 也帶過團隊,最後還是無怨無悔地選擇了技術鑽研這條路,近年來則以做一個"有為的中年人"自許。

文章典藏
其他功能

這個部落格


Syndication