试想一下,如果三层客户端接口为:OpenQuery([ParamName1,ParamValue1,ParamName2......]),客户端 接口函数会显得非常简洁和一目了然,可以接受动态的参数名和参数值。当然,在传入参数,你还可以使用TParams做传入参数,处理起来也是很灵活和方 便。但我个人不太喜欢创建对象方式的传入参数。你还可以用字符串做传入参数,然后再解析,这种方式不是很严谨,而且敲代码的人会很累和容易导致人为录入错 误。
对比Aarry of Const数据类型,我们发现,支持vtInteger、vtBoolean、vtChar、vtExtended、vtString、 vtWideString、vtPChar、vtAnsiString、vtObject、vtClass、vtCurrency、vtVariant、 vtInt64等类型,Variant类型与Aarry of Const数据类型有一点不同,Variant类型是一种简单类型,原则上是自动释放内存的数据类型,不能接受对象,因此没有TObject和 TClass类型。Aarry of Const数据类型也没有TDateTime类型,TDateTime本质就是浮点型,如果处理TDateTime不好,很容易将TDateTime当成 浮点数处理。所幸的是,Aarry of Const数据类型也支持Variant类型,而Variant类型包容了TDateTime。
约定胜于配置。对于传入TOjbects类型,我们一般默认为TStream类型,如果是非TStream类型,就做失败处理。你也想传入TField类 型,将其转换为Stream,然后到中间件那边,再序列化为TField。我个人认为,TField本身附加了太多的属性和数据,这样的效率会很低,是 C/S思想的约束。中间件与客户端的交互,本质就是简单数据的交互而已。简单的东西往往是最高效。
//下面的函数是TVarRec与Variant转换,其中细节部分,你可以根据需要自定义取舍。
function ValueFromVarRec(VarRec: TVarRec): Variant;
var
Value: Variant;
begin
with VarRec do
case VType of
vtInteger: Result := VInteger;
vtBoolean: Result := VBoolean;
vtChar: Result := VChar;
vtExtended: Result := VExtended^;
vtString: Result := VString^;
vtWideString : Result := widestring(VWideString^);
vtPChar: Result := VPChar^;
vtAnsiString: Result := string(VAnsiString);
vtObject:
begin
if VarSameValue(VObject.ClassName,'TMemoryStream') then
StreamToVariant(TMemoryStream(VObject),Result)
else
raise Exception.CreateFmt('不支持对象类型:%s!请将其转换为 varray of byte ', [VObject.ClassName]);
end;
vtClass:
begin
raise Exception.CreateFmt('不支持Class类型:%s! ', ['vtClass']);
end;
vtCurrency: Result := CurrToStr(VCurrency^);
vtVariant:
begin
Value := VVariant^;
if VarType(Value) = varDate then
Result := VarToDateTime(Value)
else if VarIsArray(Value) then //流类型
Result := Value
else
Result := VarToStrDef(Value, '');
end;
vtInt64: Result := VInt64^;
else
Result := Null;
end;
end;
假如参数为 const Args:Array of Const
只需循环取数即可:
for i := Low(Args) to High(Args) do
Value := ValueFromVarRec(Args[i])
......................
对于TDateTime类型,可直接传入,编译器会很聪明的将TDateTime改为Variant类型,如果你不放心
可以使用 VariantFromDateTime(Now())传入。