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

由於轉檔程式要輸出固定寬度的文字欄位,所以要視字串長度在後方補足空白。因中文字在不同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的分享。


Comments

# by nolem

如果先轉成 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~~ 您要試試看嗎?

# by Jeffrey

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

Post a comment