UnicodeをDelphi7に保存するバグはありますか?
最近、Delphi7を使用してUnicodeプログラムを実行すると、SQLステートメントにUnicode文字がある場合、TadoCommandコンポーネントを使用してSQLステートメントを実行する場合、そのような問題を発見しました。 TTNTADOQUERYの使用には当てはまります(パラメーターの使用はCarled Codeがあることではありません。ここでは、純粋なSQLメソッドについてのみ説明します)。ただし、TadoCommand自体はWidestringをサポートしており、CommandTextプロパティも広いタイプです。 Tadocommandのいくつかの属性値を変更しようとしましたが、ParamCheckプロパティがfalseに設定されている限り、Unicode文字を正常に保存し、Trueに設定すると、Carled Codeが表示されます。なぜこれが起こるのですか?このプロパティは、Unicode自体とは何の関係もないようです。 Tadocommandがあるadodb.pasファイルを研究することで、問題を見つけました。
手順tadocommand.AssignCommandText(const Value:widestring; loading:boolean);
手順initparameters;
var
I:整数;
リスト:TPARAMETERS;
nativecommand:string;
始める
リスト:= tparameters.create(self、tparameter);
試す
nativecommand:= list.parsesql(value、true);
{既存の値を保持}
list.AssignValues(パラメーター);
CommandObject.CommandText:= nativeCommand;
読み込まれていない場合(接続(接続)または(接続ストリング<> ''))
始める
試す
setConnectionFlag(cfparameters、true);
試す
{サポートされている場合、サーバーから追加のパラメーター情報を取得}
parameters.internalrefresh;
{サーバーから追加のパラメーター情報を使用して、リストを初期化する}
parameters.count = list.countの場合
for i:= 0 to list.count -1 do
始める
list [i] .datatype:= parameters [i] .datatype;
list [i] .size:= parameters [i] .size;
list [i] .numericscale:= parameters [i] .numericscale;
list [i] .precision:= parameters [i] .recision;
list [i] direction:= parameters [i] direction;
list [i] .attributes:= parameters [i] .attributes;
終わり
ついに
setConnectionFlag(cfparameters、false);
終わり;
を除外する
{サーバーがパラメーター情報を提供できない場合、エラーを無視します}
終わり;
list.count> 0の場合
parameters.Assign(list);
終わり;
ついに
list.free;
終わり;
終わり;
始める
if(commandType = cmdtext)および(value <> '')とparamcheck then
initparameters
それ以外
始める
CommandObject.CommandText:= value;
ロードしていない場合は、parameters.clear;
終わり;
終わり;
この声明を見てください:
if(commandType = cmdtext)および(value <> '')とparamcheck then
initparameters
つまり、ParamCheckが真実である場合、initparametersプロセスが実行されます。
まず、変数を定義します。
nativecommand:= list.parsesql(value、true);
{既存の値を保持}
list.AssignValues(パラメーター);
CommandObject.CommandText:= nativeCommand;
ここでは、値は幅が広く、list.parseSqlは文字列タイプを返し、この方法ではstring型変数も文字列型変数に配置され、nativecommandがcommandobject.commandtextに割り当てられます。 CommandObject.CommandTextは、それに割り当てるべき最も広い値を取得しないようにします。
ソリューションも非常にシンプルです(Delphiソースプログラムを変更したくない場合)ParamCheckをfalseに設定するだけです(DelphiはDefault Default to Paramcheck to True)。