bestlong 怕失憶論壇's Archiver

bestlong 發表於 2011-12-14 17:25

Delphi + ZeosLib + Tnt + MySQL 使用 UTF-8 編碼

首先要確實做好 MySQL 安裝設定與檢查
檢查 MySQL Server 的設定檔 my.ini (my.cnf) 內容
確認在 [mysql] 與 [mysqld] 兩個區段內都要有 default-character-set=utf8 的設定。
如果沒有就請在兩個區段都加上後,重新啟動 MySQL Server 一次讓有變更的設定生效。

然後用 MySQL 命令列工具連線檢查系統變數的狀況,請用 show variables like 'char%'; 命令來檢視:



如果得到如上方圖片中每個 character_set 除了 filesystem 為 binary 其他變數都是 utf8 的結果就可以了。

建立資料庫時需要注意必須使用 utf8 編碼。

建立資料表時也要注意必須使用 utf8 編碼。

在 MySQL 部分處理到這樣就可以了,再來進入到程式開發的部分。

開啟 Delphi 開發環境並建立一個新專案。

使用檔案總管,複製 libmysql.dll 到專案目錄下,然後回到 Delphi IDE。
(libmysql.dll 可以到 MySQL for windows 的安裝目錄下的 lib 子目錄內找到,要 32 bit 版本的)

在 Form1 上加入 TZConnection 元件並設定屬性:

  Name: zConn
  Protocol: 選擇 mysql-5
  HostName: MySQL 資料庫伺服器的名稱
  Database: 資料庫的名稱
  User: 連線到 MySQL 的使用者名稱
  Password: 連線到 MySQL 使用者的密碼

然後將 Connected 設為 True 進行連線
接著在 Form1 上增加 TZQuery 元件並設定屬性:

  Name: zqryM
  Connection: zConn
  SQL: select * from product

接著在 Form1 上增加 TDataSource 元件並設定屬性:

  Name: dsM
  DataSet: zqryM

接著在 Form1 上增加 TTntDbGrid 元件並設定屬性:

  DataSource: dsM

然後增加程式碼,使程式啟動後就開啟 ZQuery[code]procedure TForm1.FormCreate(Sender: TObject);
begin
  zqryM.Open;
end;
[/code]結果文字欄位的內容卻是看到問號



再來檢查連線到 MySQL 的系統變數狀況,將 zqryM.SQL 改為 show variables like 'char%' 後執行程式:



可以看到 character_set_client 與 character_set_connection 以及 character_set_results 居然是 latin1 的狀況,當然有問題。

這個狀況有兩個解決方案,Zeos 設定參數方法與 MySQL 命令的方法。

Zeos 設定參數方法:
  在 TZConnection 設定 Properties 屬性加入一行 codepage=utf8 就可以了

MySQL 命令的方法:
  在網站開發環境最常用的解決方案就是執行 set names utf8 命令,所以在 OnAfterConnect 事件加入程式碼:[code]procedure TForm1.zConnAfterConnect(Sender: TObject);
var
  qy: TZReadOnlyQuery;
begin
  qy := TZReadOnlyQuery.Create(nil);
  qy.Connection := zConn;
  qy.SQL.Text := 'SET NAMES UTF8';
  qy.ExecSQL;
  qy.Free;
end;
[/code]選擇一種解決方案應用之後,再次執行程式看一下連線的系統變數狀況:



解決了連線參數的問題,再將 zqryM.SQL 改回 select * from product 後執行程式,居然這次變成顯示亂碼:



這又怎麼了?
因為此時的 TZQuery 元件內的欄位是基於 SQL 內容而動態產生的,所以是用 TStringField 元件來處理,遇上 UTF8 編碼當然就不支援了。

現在開啟 zqryM 的 Fields Editor 後 Add all fields 就會看到文字欄位都是用 TStringField 元件[code]type
  TForm1 = class(TForm)
    zConn: TZConnection;
    dsM: TDataSource;
    zqryM: TZQuery;
    TntDBGrid2: TTntDBGrid;
    zsqlmntr: TZSQLMonitor;
    Panel1: TPanel;
    dbnvgr: TDBNavigator;
    zqryShowVar: TZQuery;
    dsShowVar: TDataSource;
    zqryMproduct_id: TIntegerField;
    zqryMprod_num: TStringField;
    zqryMprod_name: TStringField;
    procedure FormCreate(Sender: TObject);
    procedure zConnAfterConnect(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;
[/code]進入 unit 檔手動將 TStringField 改成 TTntStringField 元件,然後還要同時修改 .dfm 內也就是 Form 原始碼的部分[code]  object zqryM: TZQuery
    Connection = zConn
    SQL.Strings = (
      'select * from product')
    Params = <>
    Left = 164
    Top = 300
    object zqryMproduct_id: TIntegerField
      FieldName = 'product_id'
      Required = True
    end
    object zqryMprod_num: TStringField
      FieldName = 'prod_num'
      Size = 135
    end
    object zqryMprod_name: TStringField
      FieldName = 'prod_name'
      Size = 300
    end
  end
[/code]同樣手動將 TStringField 改成 TTntStringField 元件,然後儲存後執行程式:



經過幾番波折,終於看到正常的中文字了。
頁: [1]

Powered by Discuz! X1.5 Archiver   © 2001-2010 Comsenz Inc.