鉴于以下
{------------------------------------------------------------------------------}
function TTestClass.NewQuery(const ASql : String) : TSqlQuery;
begin
Result := TSqlQuery.Create(FConn);
Result.SQLConnection := FConn;
Result.Sql.Text := ASql;
Result.Prepared := True;
end;
{------------------------------------------------------------------------------}
procedure TTestClass.ExecuteSql(const ASql : String);
begin
with NewQuery(ASql) do
try
ExecSql();
finally
Free;
end;
end;
如何创建一个ExecSql
填充查询参数的方法?
我试过这个重载方法:
{------------------------------------------------------------------------------}
procedure TTestClass.ExecuteSql(const ASql : String; const ParamVals : Array Of Variant);
var
i : integer;
Qry : TSqlQuery;
begin
Qry := NewQuery(ASql);
with Qry do
try
for i := Low(ParamVals) to High(ParamVals) do
Qry.Params[i].Value := ParamVals[i];
ExecSql();
finally
Free;
end;
end;
但我收到错误消息:
MyProj.exe 项目引发异常类 EDatabaseError,并带有消息“参数 'SomeParam' 没有值”。
观察 Parameter[0] 显然表明该值已设置 - 参数名称与我预期的一样。谁能建议我做错了什么?
而且我过去曾因使用“变体数组”而受到批评——我想知道是否有更好的方法。
谢谢大家。
我发现了一些有趣的东西:
ParamByName('SomeParam').Value := 1234567;
产生相同的错误消息,而
ParamByName('SomeParam').AsInteger := 1234567;
才不是。
我使用 DBExpress 已经很多年了——我忘记了什么吗?
编辑
我想出了一个可行的方法,但对它不满意;通过检查 VALUE 的变体类型,我设法得到了一些结果
{------------------------------------------------------------------------------}
procedure TMyTestCase.SetParamValues(const AQuery : TSqlQuery; const ParamVals : Array Of Variant);
var
i : Integer;
begin
for i := 0 to AQuery.Params.Count - 1 do begin
case VarType(ParamVals[i]) of
varEmpty : AQuery.Params[i].AsInteger := VarNull; //The variant is Unassigned.
varNull : AQuery.Params[i].AsInteger := VarNull; //The variant is Null.
varAny : AQuery.Params[i].AsInteger := VarNull; //Represents a Variant that can hold any value.
varSmallint : AQuery.Params[i].AsInteger := ParamVals[i]; //16-bit signed integer (type Smallint in Delphi, short in C++).
varInteger : AQuery.Params[i].AsInteger := ParamVals[i]; //32-bit signed integer (type Integer in Delphi, int in C++).
varSingle : AQuery.Params[i].AsFloat := ParamVals[i]; //Single-precision floating-point value (type Single in Delphi, float in C++).
varDouble : AQuery.Params[i].AsFloat := ParamVals[i]; //Double-precision floating-point value (type double).
varCurrency : AQuery.Params[i].AsFloat := ParamVals[i]; //Currency floating-point value (type Currency).
varDate : AQuery.Params[i].AsDateTime := ParamVals[i]; //Date and time value (type TDateTime).
varOleStr : AQuery.Params[i].AsString := ParamVals[i]; //Reference to a dynamically allocated UNICODE string.
varDispatch : AQuery.Params[i].AsInteger := VarNull; //Reference to an Automation object (an IDispatch interface pointer).
varError : AQuery.Params[i].AsInteger := VarNull; //Operating system error code.
varBoolean : AQuery.Params[i].AsBoolean := ParamVals[i]; //16-bit Boolean (type WordBool).
varVariant : AQuery.Params[i].AsInteger := VarNull; //Indicates another variant.
varUnknown : AQuery.Params[i].AsInteger := VarNull; //Reference to an unknown object (an IInterface or IUnknown interface pointer).
varShortInt : AQuery.Params[i].AsInteger := ParamVals[i]; //8-bit signed integer (type ShortInt in Delphi or signed char in C++).
varByte : AQuery.Params[i].AsInteger := ParamVals[i]; //A Byte.
varWord : AQuery.Params[i].AsInteger := ParamVals[i]; //Unsigned 16-bit value (Word).
varLongWord : AQuery.Params[i].AsInteger := ParamVals[i]; //Unsigned 32-bit value (type LongWord in Delphi or unsigned long in C++).
varInt64 : AQuery.Params[i].AsInteger := ParamVals[i]; //64-bit signed integer (Int64 in Delphi or __int64 in C++).
varStrArg : AQuery.Params[i].AsString := ParamVals[i]; //COM-compatible string.
varString : AQuery.Params[i].AsString := ParamVals[i]; //Reference to a dynamically allocated string (not COM-compatible).
varArray : AQuery.Params[i].AsInteger := VarNull; //Indicates a Variant array.
varByRef : AQuery.Params[i].AsInteger := VarNull; //Indicates that the variant contains a reference as opposed to a value.
varTypeMask: AQuery.Params[i].AsInteger := VarNull; //
end;
end;
end;
我肯定错过了一步 - 为什么查询参数没有类型?
再次编辑
我目前的“最佳”解决方案是依靠程序员提供正确的类型和数量的值。我已经在上面发布了完整的 SetParamValues() 方法。这绝不是经过彻底测试,但希望它会对某人有所帮助。