XE7 FireDAC FireBird Blob UTF8 |
|
pcplayer99
尊榮會員 發表:146 回覆:790 積分:632 註冊:2003-01-21 發送簡訊給我 |
DELPHI 从有 DBExpress 以来,一直到 XE6,如果用 DBExpress 连接 FireBird 数据库,而数据库的 CharSet 是 UTF8 的话,其中的 Blob 用 DBMemo 来做用户界面,按照以下方式处理:
FireBird -- SQLConnection -- SQLDataSet -- DataSetProvider -- ClientDataSet -- DataSource -- DBMemo 如果用 UTF8 ,那么中文直接输入到 DBMemo 里面,提交到 DataBase 里面去,下次再打开,DBMemo 里面显示的是乱码。 现在 XE7 带来了 FireDAC,我测试,如果把 DBExpress 的 SQLConnection 和 SQLDataSet 替换为 FireDAC 的元件,这个问题解决了。 对 FireDAC 和 FireBird 的进一步测试,发现: 1. 搜索 UTF8 VarChar 字段,用 like 语句,可以正确搜索; 2. 搜索 UTF8 Blob 字段,用 like 语句,可以正确搜索; 所以,如果做正式产品,之前DELPHI推荐的 DBExpress 应该换成 FireDAC 了。 |
P.D.
版主 發表:603 回覆:4038 積分:3874 註冊:2006-10-31 發送簡訊給我 |
|
P.D.
版主 發表:603 回覆:4038 積分:3874 註冊:2006-10-31 發送簡訊給我 |
個人實測的部份
系統部份 FireBird 2.11 Blob Field Win7 x64 XE7 Server端 DataSnap FireDAC (DataSetProvidor FBdriver FDconnection FDQuery) app端(Android) FireDAC (SQLconnection DSprovidorconnect ClientDataSet) 由手機端直接連接 Server端, 並由手機端app存入資料到server端 中文的部份(TwoBytes) 與 XE6 一樣還是亂碼 (透過 DBMemo 直接查看) |
pcplayer99
尊榮會員 發表:146 回覆:790 積分:632 註冊:2003-01-21 發送簡訊給我 |
|
P.D.
版主 發表:603 回覆:4038 積分:3874 註冊:2006-10-31 發送簡訊給我 |
如果我在server端的 pc app直接進行 dbmemo 的編輯及顯示, dbmemo 是可以完整顯示 unicode 內容,
可能是 在 fm2 的 ClientDataSet 與 server DataSnap 在處理 dbmemo 上沒有辦法直接轉碼吧! 我猜! 所以還是只能用 Memo (pc端) 轉碼 dbMemo 內容後才能正常顯示 ===================引 用 pcplayer99 文 章=================== 目前我的测试代码是 RUN 在 XP 上的,没有乱码问题。但如果用 DBExpress 去连接 FireBird 则会有乱码。之前我的解决办法也是自己解码,用 TMemo 去显示。现在直接用 DBMemo 可以显示了。 |
GrandRURU
站務副站長 發表:240 回覆:1680 積分:1874 註冊:2005-06-21 發送簡訊給我 |
我想了解一下你們的 Firebird 的 Blob 設定
以及 dbExpress driver 用的是哪一家的? 我目前用的是 dbExpress Driver for Firebird 以下是我的 DB code /******************************************************************************/ /*** Generated by IBExpert 2010.03.19 2014/09/24 上午 11:56:28 ***/ /******************************************************************************/ SET SQL DIALECT 3; SET NAMES UTF8; SET CLIENTLIB 'D:\DBX棒棒\fbembed.dll'; CREATE DATABASE 'D:\DBX棒棒\TestUTF8.fdb' USER 'DBX' PASSWORD 'LIKEDBX' PAGE_SIZE 16384 DEFAULT CHARACTER SET UTF8; /******************************************************************************/ /*** Tables ***/ /******************************************************************************/ CREATE TABLE NEW_TABLE ( A1 INTEGER NOT NULL, A2 BLOB SUB_TYPE 0 SEGMENT SIZE 80, A3 VARCHAR(50), A4 BLOB SUB_TYPE 1 SEGMENT SIZE 16384 ); /******************************************************************************/ /*** Primary Keys ***/ /******************************************************************************/ ALTER TABLE NEW_TABLE ADD CONSTRAINT PK_NEW_TABLE PRIMARY KEY (A1); Delphi 2009 擷圖 我想應該是差在 BLOB SUB_TYPE 設定而已吧 可以再多測試一下嗎? |
P.D.
版主 發表:603 回覆:4038 積分:3874 註冊:2006-10-31 發送簡訊給我 |
|
GrandRURU
站務副站長 發表:240 回覆:1680 積分:1874 註冊:2005-06-21 發送簡訊給我 |
|
P.D.
版主 發表:603 回覆:4038 積分:3874 註冊:2006-10-31 發送簡訊給我 |
|
GrandRURU
站務副站長 發表:240 回覆:1680 積分:1874 註冊:2005-06-21 發送簡訊給我 |
看來 FireBird 的 Driver 還是有些問題
我這邊收集了一些解決方法: 不論 Firebird Blob 欄位的 sup_type 是 0 還是 1 (只有 0 / 1 / 2,2 是 Firebird 資料庫內專用,程式只能使用 0 和 1 ) 寫入 Blob: Sender.AsBytes := TEncoding.UTF8.GetBytes(ENCODE_STRING); 讀取 Blob: Text := TEncoding.UTF8.GetString(CDS.Fields[1].AsBytes); 查詢: SQLQuery1.Params.Items[0].AsBlob := TEncoding.UTF8.GetBytes(STRING); ===================引 用 P.D. 文 章=================== 試過 0,1,2,3,4 ... 都不行, 反而更亂, 只有 0 還可以接受一些 另外有一種 sub_type text 也試過, 一樣亂 但我前面有強調, 如果是在pc端操作(不透過 DataSnap 運轉)是沒有問題, 有問題的是, 手機(ClientDataSet) 後端(DataSnap FireDAC)會出現這樣的情況 不管 blob 怎麼去定義或完全不定義 |
pcplayer99
尊榮會員 發表:146 回覆:790 積分:632 註冊:2003-01-21 發送簡訊給我 |
以下是我几年前的测试结果记录:
用 IBDataBase IBTable 来连接 FireBird 2.1 的有 UTF8 字段的数据库。 IBDataBase.Params 如下: user_name=sysdba password=masterkey lc_ctype=UTF8 如果不写 lc_ctype=UTF8 则返回来的是乱码。 DBGrid, DBMemo 指向 DataSource1。 1. 如果 DataSource1 指向 IBTable,则可以正常显示汉字,也能正常输入汉字并保存。保存后重新打开程序能看到保存结果正常。 2. 如果用 DBGrid/DBMemo -> DataSource -> ClientDataSet -> DataSetProvider -> IBTable,则打开表显示汉字正确。但如果修改 DBMEMO 的内容然后提交,保存到数据库里的内容是错误的。再次加载就能显示错误内容。 3. ClientDataSet 连接到 IBTable 时,设计期创建的字段,varchar 对应 TWideStringField,Blob字段对应的是 TMemoField,但此时 DBMEMO显示乱码;手动在设计期把该字段改为 TWideMemoField 则显示正确。 4. 如果用 DBExpress 去连接 FB,ClientDataSet 指向 SQLDataSet,则 DBMemo 里面显示乱码。但输入的汉字提交后保存到数据库是正确的。只是重新加载的时候显示乱码。这些提交的内容如果用 IBTable 来看是正确的。 5. 如果不用 ClientDataSet,直接将 DBGrid/DBMemo 连接到 IBTable,输入、输出的汉字都正常。 =========== 从 fb 官网下载 ODBC 驱动安装后,用 ADOConnection ADODataSet,发现 BLOB 对应的 DBMEMO 里面全是显示乱码。看来这条路走不通。 ============ DELPHI XE3 底下,从 BLOB 字段获取到的数据要正确显示,必须这样: procedure TForm1.Button3Click(Sender: TObject); var B: TBytes; begin B := DataModule2.CldUserID.FieldByName('Info').AsBytes; Memo1.Lines.Add(TEncoding.UTF8.GetString(B, 0, Length(B))); end; 也就是说,对 UTF8 的 BLOB字段,Field.AsString 返回不了正确的字符串,必须自己解码。但是,DataModule2.CldUserID.FieldByName('INfo').AsString := Memo1.Lines.Text; 是可以将字符串正确保存进UTF8 的 BLOB 字段的。 关于这个问题,我有在 https://forums.codegear.com/message.jspa?messageID=557466#557466 提交。也有在DELPHI的质量中心提交。 ========================================================= 总之,如果用 DBExpress 去连接 FireBird 然后通过 TClientDataSet 把数据给 TDBMemo ,UTF8 的 BLOB 就会出乱码。 但如果改用 FireDAC 就没事了。 我的测试环境有2种,一种是在一个 Program 里面,DBExpress(SQLConnection, -- SQLDataSet) --- DataSetProvider --- ClientDataSet --- DBMemo ,其中 DBExpress 的 FireBird driver 是 Delphi 自己带的,没用第三方的。 另一种是 DBExpress - DataSetProvider -- WebService ---- HTTPRIO or SOAPConnection -- ClientDataSet -- DBMemo 这里的 Client 也是 RUN 在 XP 上的,不是手机。 以上两种方式测试,都会乱码。 以上两种方式,只要把 DBExpress 替换为 FireDAC,就一切正常了。 |
P.D.
版主 發表:603 回覆:4038 積分:3874 註冊:2006-10-31 發送簡訊給我 |
本站聲明 |
1. 本論壇為無營利行為之開放平台,所有文章都是由網友自行張貼,如牽涉到法律糾紛一切與本站無關。 2. 假如網友發表之內容涉及侵權,而損及您的利益,請立即通知版主刪除。 3. 請勿批評中華民國元首及政府或批評各政黨,是藍是綠本站無權干涉,但這裡不是政治性論壇! |