Delphi7中儲存unicode的BUG?

2021-03-31 21:11:51 字數 3312 閱讀 2555

delphi7

中儲存unicode

的bug

?近日,在用

delphi7

做unicode

的程式時發現了這樣乙個問題,就是使用

tado***mand

元件執行

sql語句時,如果

sql語句中有

unicode

字元,儲存在資料庫裡會出現亂碼,使用

ttntadoquery

也是一樣(使用引數方式不會出現亂碼,這裡只討論純

sql的方式)。但是

tado***mand

本身是支援

widestring

的呀,***mandtext

屬性也是

widestring

型別的,為什麼會出現這個問題呢?我試著改變

tado***mand

的幾個屬性值,發現了乙個怪現象,只要把

paramcheck

屬性置為

false

就可以正常的儲存

unicode

字元,而置為

true

時就出現亂碼。為什麼會出現這種情況?這個屬性看起來和

unicode

本身沒有任何關係,究竟是什麼原因導致了亂碼的發生呢?我通過研究

tado***mand

所在的adodb.pas

檔案,發現了問題的所在,我們看一下

bug所在的過程:

procedure tado***mand.assign***mandtext(const value: widestring; loading: boolean);

procedure initparameters;

vari: integer;

list: tparameters;

native***mand: string;

begin

list := tparameters.create(self, tparameter);

trynative***mand := list.parsesql(value, true);

list.assignvalues(parameters);

***mandobject.***mandtext := native***mand;

if not loading and (assigned(connection) or (connectionstring <> '')) then

begin

trysetconnectionflag(cfparameters, true);

tryparameters.internalrefresh;

if parameters.count = list.count then

for i := 0 to list.count - 1 do

begin

list[i].datatype := parameters[i].datatype;

list[i].size := parameters[i].size;

list[i].numericscale := parameters[i].numericscale;

list[i].precision := parameters[i].precision;

list[i].direction := parameters[i].direction;

list[i].attributes := parameters[i].attributes;

endfinally

setconnectionflag(cfparameters, false);

end;

except

end;

if list.count > 0 then

parameters.assign(list);

end;

finally

list.free;

end;

end;

begin

if (***mandtype = cmdtext) and (value <> '') and paramcheck then

initparameters

else

begin

***mandobject.***mandtext := value;

if not loading then parameters.clear;

end;

end;

看看這一條語句:

if (***mandtype = cmdtext) and (value <> '') and paramcheck then

initparameters

也就是當

paramcheck

為true

時,會執行

initparameters

過程,我們看看這個

initparameters

過程中發生了什麼:

首先它定義個乙個變數:

native***mand: string;

,注意,是

stirng

不是widestring

;我們接著往下看:

native***mand := list.parsesql(value, true);

list.assignvalues(parameters);

***mandobject.***mandtext := native***mand;

在這裡,

value

是widestring

型別的,而

list.parsesql

返回的是

string

型別的,同時

native***mand

也是string

型別的,就這樣,乙個好好的

widestring

的變數被放到了

string

型別的變數當中,然後又把

native***mand

賦給了***mandobject.***mandtext

,因此導致了

***mandobject.***mandtext

並沒有得到應該賦給它的

widesting

值,這也就最終導致了儲存

unicode

時亂碼的發生。

解決方法也很簡單,(如果你不願意修改

delphi

源程式的話)只需要把

paramcheck

置為false

就可以了(

delphi

預設把paramcheck

置為true

)。

Delphi 7 中DBGrid的排序。

procedure tfrmtracereport.dbgrid1titleclick column tcolumn var sortfield,fieldtitle string begin sortfield column.field.fieldname fieldtitle column.ti...

Delphi7遠端除錯

自己的開發機器稱為主機,執行程式的機器稱為目標機 一 在主機編譯執行程式 1 project options linker中的exe and dll options選項組中的include remote debug symbols打上勾,這樣就可以生成rsm為副檔名的檔案,該檔名稱於你的專案同名。2...

Delphi7 動態陣列

初學delphi,感覺.這感覺就是寫 太費勁了,已經習慣了c 那種信手拈來,不能說pascal不適應只能說還是費勁,可能是d7太老了,也可能是我還沒有上道兒,就這麼著吧,下面簡單的寫倆函式作為參考,修改修改可以當c 中的list 用arr array of string procedure add ...