2012-01-18

Navicat 有兩種UTF8的模式嗎??

這兩天在幫老婆大人轉檔的過程中發現了個怪問題,其實以前就有遇過只是沒去深入去探究可能的原因,下面是測試的畫面:

圖1.mysql.exe 直接連接畫面1(MySQL預設狀態)

圖2.mysql.exe直接連接畫面2(MySQL預設狀態)

圖3.localhost-Big5 Connection

圖4.localhost-Big5 Console

圖5.localhost-UTF8 Connection

圖6.localhost-UTF8 Console

圖7.localhost-UTF8-Defaule

圖8.localhost-UTF8-Defaule Console




























































































































































































































圖1、圖2是用mysql-4.1.22-w32.exe以系統預設安裝後的狀態,圖3、圖5、圖7則是三個Navicat上建立的Connection,不同的只是在Encoding的部份設定不同,但是設定的不同卻造成了相同也不同的結果,圖4、圖6、圖8分別是各Connection連線後,以Navicat提供的Console功能,執行show variables like '%c' 所show出的MySQL對於character set的狀態。
圖3與圖5的Encoding設定分別是950 (ANSI/OEM - Traditional Chinese Big5)和65001 (UTF-8),但是玄了,從各別的Console畫面圖4、圖6卻是完全相同,各個character set都沒有變更,再以實際的連線去select資料出來看,卻又沒辦法正常顯示對方連線時可正常顯示的資料。
圖5與圖7的Encoding設定都是UTF-8,但是圖7的UTF-8是勾選 Use MySQL character set而成的,原則上兩個連線都是以UTF-8為character set,但是從Console畫面圖6、圖8來看使用Use MySQL character set的選項才有辦法造成真的UTF-8的存儲使用環境。在實際連線測試select資料也是同樣無法正常顯示對方連線時可正常顯示的資料。
就目前來講這樣的測試還無法證明什麼,到底是MySQL的問題還是Navicat的Bug,不過自己覺得MySQL的character set的問題真的是個大麻煩,但也因為Navicat這個對UTF-8的怪原因,讓人浪費了不少zZZ的時間,不過至少知道一個結果..那就是如果要使用Navicat將原先Big5編碼的資料庫轉為UTF-8編碼時,UTF-8 Connection properties 的 "Use MySQL character set" 一定要勾啦!!

2012-01-17

MySQL Big5 to UTF8 快速轉碼

延伸閱讀Navicat 有兩種UTF8的模式嗎?? <-- 有要做的人一定要先看

昨天要幫老婆大人把客戶從MySQL dump出來的資料,從原先的Big5轉成UTF8再塞進去MySQL裡。原始檔案有將近900M,有點大所以大部份的編輯軟體都拿他沒輒,所以就開到Linux裡用iconv直接轉,轉是轉完了但是總會有"\?"的問題造成匯入不成功,去問了一下G大這有可能是換行字元的問題,為了快速找到解決方案就先把問題的研究先放著,解決問題優先。
[Navicat]是一套資料庫管理工具支援多種資料庫,可下載試用。它本身提供Data Transfer的功能可以直接讓線上的資料庫轉到另一個資料庫或輸出成檔案。轉換細節如下:


環境:Server: VMwarePlayer3.1.5 + Debian6.0.3 + MySQL 5.1.49
          Client: WinXP with SP3 + Navicat10


























  1. 在Navicat環境下,建立兩個Connections,一個Encoding設成950 (ANSI/OEM - Traditional Chinese Big5),另一個設成65001 (UTF-8)



  2. 點選 Tools -> Data Transfer -> General,設定Source Connection為Big5的那個,當然Target Connection就得設成UTF8的那個了,Database依需求設定



  3. 在Data Transfer畫面下點選Advanced,依照你的需求增減相關的選項,在本例中我將Include character set及Use hexadecimal format for BLOB取消。Include character set如果設定會把目的table也設成Source table的character設定,所以取消;至於Use hexadecimal format for BLOB則是因為我的資料庫有使用到BLOB的欄位,轉換時會造成錯誤,所以取消。



  4. 接著就按Start等待結果啦~

2012-01-15

Delphi7 Lite

在網路上找東找西時,看到了這個東東[Delphi7 Lite],甚至 Embarcadero.Delphi.XE2.Lite 都也有。就去載了D7LiteFullEdition來踹踹看和CD安裝有和差別,載下來也不過7xMbyte,從資料來看除了已加入一些patch外也再加入一些加強版的套件,裝完後給我的感覺就是一個加強版的D7,接著再把常用的Component裝起來,和安裝版沒什麼差別也沒有異樣,把之前寫的Code拿來重編也都正常無誤。
會看到它是為了找看看在Delphi上是否有支援Hash這個東東,因為在Perl上常用到也覺得粉好用,是的找到了在IniFiles裡有個THashedStringList可以做得到,而彼岸的網友也把THashedStringList和TStringList做了效能上的比較他使用的環境是D7.2+XPSp2,這個D7.2引起我的興趣,因為好像沒聽過有出7.2版,挖著挖著連D7.3版都出現了。從一開始的新鮮到後來的佩服,佩服他們對於某些東西的深度了解並實行。現在常找到的技術文章有極大多數都是彼岸的大作,這樣的情況其實已經持續了多年,這岸的我們應該要警惕。

2012-01-09

Delphi XE2 UTF8測試

由於Delphi7不支援UTF8,造成程式中對於UTF8字元處理及顯示上的不便,因而興起測試一下目前新版本的支援度如何。在測試前先在網路上看一下網友使用的狀況,其中看到一條消息就是XE2已經有內建支援Regular Expressions了,真是讓人高興啊!!


目標主要測試TMemo、TComboBox、TiniFiles及RegularExpressions對UTF8的支援度。有畫面有真象。測試的過程有發現一些事,應該不算新鮮事應該也許早在Delphi2009就支援了。
  1. 一開始當然是先編個最基礎的空AP玩玩,看完真的很大便,Debug版要6M,找了半天弄個了Release版也要1.5M,哇~真是粉大~~,可能剛從D7過來的關係不太適應。
  2. TEncoding,使用TMemo和TStrings讀寫檔案時,可指定寫入檔案的編碼如:TEncoding.UTF8,預設好像是TEncoding.ANSI,問了一下G大好像在Delphi2007就支援了,也有看到用Delphi2009寫的Code。這樣就不必每次要先準備好對的格式的文字檔來stand by了。
    Ex:
    Memo1.Lines.SaveToFile('xx.ini',TEncoding.UTF8);
    -參考資料
  3. TIniFile差點讓人從椅子上掉下來,一開始使用D7慣用的語法去開*.ini,慘了讀不出UTF8格式的,但是ANSI的卻可以。心裡幹譙一陣嘀咕著要改怎不全部一起改咧?後來想想那麼大的公司應該沒那麼笨吧?
    開始到程式安裝的地方把Inifiles*.*的檔案挖出來,找到"System.IniFiles.pas",到裡面去找TEncoding這key word,還好讓我在TMemIniFile class找到。使用方式和TIniFile一樣,只是在宣告時要把TIniFile改宣告TMemIniFile就可以指定TEncoding.UTF8了。
    Ex:
    oIni: TMemIniFile;
    oIni:=TMemIniFile.Create('.\xx.ini',TEncoding.UTF8);
    -參考資料
  4. Regular Expressions是最讓人喜出望外的,在其他部份測試完要進行RE的部份時,正不知如何下手就直接問G大吧,結果找到[Embarcadero原廠資料],原來XE2的RE是承自於TPerlRegEx,讓原先的TPerlRegEx的user可以完全無痛更換開發環境,而且直接支援UTF8String解決了原先D7+TPerlRegEx對UTF8的處理問題。
    既然可以直接使用TPerlRegEx就不作他想了,使用上必須宣告uses System.RegularExpressionsCore,不可宣告uses RegularExpressions。在實際使用上目前發現有一點和D7版的不同,原本熟悉的SubExpressions[n]不見了,取而代之的是Groups[n],至於其他像replace、split有沒差異?因為少用就沒測了。
    Ex:
    uses System.RegularExpressionsCore;
    oRE: TPerlRegEx;
    -參考資料
其他XE2還有些特異功能像FireMonkey、跨Mac、支援x64等,因為沒環境就先不測了。
結論:綜合以上各點已滿足自己小小的需求,讓人粉想換個開發環境,唯一的缺憾就剩執行檔吃了歐羅肥的問題了。


2012-01-08

Delphi7上Unicode的問題

Delphi7是我慣用的開發工具,之前完全不考慮更換版本的最大原因就是新的版本真的是越來越肥了,重點讓人最不爽的是會在系統上裝一堆不曉得用不用得上的東東,就像MS的VisualStudio一樣。

這次在改寫[EzNetRadio]時加入了一個新平台[Now.in],在Web上的編碼UTF-8已是主流,HichannelNow.in皆然,不過Hichannel站台名稱上不會使用特殊字元所以在轉換及顯示上不會有問題,反之Now.in則不然,使用者強調的個人化造成站台名稱格式大相逕庭,而且有為數不少ANSI無法顯示的特殊字元,因此興起將EzNetRadio增加支援Unicode的功能。

Delphi7在Object、procedure及function的使用上,皆以AnsiString、String為主,但是Unicode的處理都必須使用WideString。在EzNetRadio中有使用到IniFile、MainMenu、PopupMenu及站台資料快速截取的靈魂TPerRegEx都必須要支援WideString及WideStringList包括Delphi7內建的字串處理函式,麻煩大了。

TntUnicodeComponents解決了*.ini上Unicode字元顯示在MainMenu及ComboBox的問題,支援WideString的IniFiles也在網上找到解決方案WideIniFiles,至於TPerlRegEx踹了半天都解決不了就只有先放棄了。

Delphi7在Unicode上是有一些解決方案,但還是缺東缺西的,像我這樣玩票的開發人員要自行開發或修改元件還是免了,因為頭髮會掉更多。

把花了一天做的測試弄個Sample以免下次又要重來。

下載Sample.zip

2012-01-02

多物件procedure共用-以Button為例

物件procedure共用在網路上有找到兩種方法:
第一種方法,只要把Button的OnClick方法指向Sample1Click即可,但是第2種方法除了必須指向Sample2Click之外,還必須設定各Button的tag屬性,以tag作為判斷的區別,目前使用上傾向第2種方法。

procedure TForm1.Sample1Click(Sender: TObject);
begin
  if Sender = Button1 then ShowMessage('Sample1-Button1')
  else if Sender = Button2 then ShowMessage('Sample1-Button2');
end;

procedure TForm1.Sample2Click(Sender: TObject);
begin
  case TComponent(Sender).Tag of
    1: ShowMessage('Sample2-Button3');
    2: ShowMessage('Sample2-Button4');
  end;
end;

Delphi ComboBox AutoComplete

在Delphi7的ComboBox,可以透過鍵盤輸入中文或英文達到快速尋找的目的,但是如果要透過程式達到一樣的效果,可以如下方式達成:

環境:Delphi7

ComboBox1.ItemIndex:=ComboBox1.Perform(CB_FINDSTRING, -1, LongInt(PChar('要找的字')));