如何在TVarRec和Variant之间进行转换?

8
有没有一种标准的方法可以在TVarRec和Variant值之间进行转换?
我想解析“array of const”,并使用这些值来填充TMSQuery中的参数。为此,我正在使用列名列表(从TMSQuery.KeyFields生成),并将数组中的值与KeyFields中的列名(按位置)匹配,然后使用列名设置相应的参数,使用ParamByName。
下面的代码是我想出的,但VarRecToVariant看起来不太优雅。有更好的解决方案吗?
  keyFields: TStringList;
    // List of table column names (keyFields.DelimitedText := query.KeyFields;)
    // e.g. Name, Age
  query: TMSQuery;
    // Parametrized query with a parameter for each field in keyFields 
    // SELECT * FROM People WHERE Age=:Age AND Name=:Name

  // If keyValues is ['Bob', 42] the resulting query should be
  // SELECT * FROM People WHERE Age=42 AND Name='Bob'

  procedure Read(keyValues: array of const);
  var
    i: Integer;
    name: string;
    value: Variant;
  begin
    ...
    for i := 0 to keyFields.Count - 1 do
    begin
      name := keyFields[i];
      value := VarRecToVariant(keyValues[i]);
      query.ParamByName(name).Value := value;
    end;
    query.Open
    ...
  end;

  function VarRecToVariant(varRec: TVarRec): Variant;
  begin
    case varRec.VType of
      vtInteger:    result := varRec.VInteger;
      vtBoolean:    result := varRec.VBoolean;
      vtChar:       result := varRec.VChar;
      vtExtended:   result := varRec.VExtended^;
      vtString:     result := varRec.VString^;
      ...
    end;
  end;

注意事项:

  • 常量数组中的值取决于查询中的参数。调用者知道这些参数,但使用数组的方法不知道期望多少个或什么类型。也就是说,我不能将方法更改为Read(name:string; age:integer)。
  • 参数不一定按照在常量数组中指定值的顺序使用。例如,keyFields被指定为“Name,Age”,但查询先使用Age再使用Name。这意味着Params [i] .Value:= keyValues [i]将无法工作。我认为仍然需要VarRecToVariant,但我正在尝试避免这种情况)。

胶带从来不是很漂亮,这基本上就是你所做的事情,将两个不同的系统连接起来。总会存在一些阻抗不匹配。 - Barry Kelly
1
顺便提一下,在VCL中已经有一个非常类似的函数:MxCommon单元中的ConvertToVariant。 - Ondrej Kelle
@TOndrej,我不知道ConvertToVariant,谢谢你提到它。 - WileCau
@Barry Kelly,是的,我想找到一种隐藏胶带的方法 :) 感谢您的评论,它证实了我需要重新思考这个问题。 - WileCau
1个回答

6

替换

procedure Read(keyValues: array of const); 

使用

procedure Read(keyValues: array of Variant); 

那么您就不需要将TVarRec转换为Variant。

谢谢,这正是我需要的侧面思考 :) 我被转换数组的细节所困扰,没有想到只需更改数组类型。 - WileCau
Variant 无法承载 TVarRec 的所有内容。 - Stefan Glienke

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接