Existe-t-il un moyen standard de convertir les valeurs TVarRec et Variant?Comment faire pour convertir entre TVarRec et Variant?
Je veux analyser un 'tableau de const' et utiliser les valeurs pour remplir les paramètres dans un TMSQuery. Pour ce faire, j'utilise une liste de noms de colonnes (générés à partir de TMSQuery.KeyFields), et en faisant correspondre les valeurs du tableau avec les noms de colonnes dans KeyFields (par position), puis en utilisant le nom de la colonne pour paramétrer ParamByName .
Le code ci-dessous est ce que j'ai trouvé, mais VarRecToVariant ne semble pas très élégant. Y a-t-il une meilleure solution?
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;
Remarques:
- Les valeurs dans le tableau de const dépendent des paramètres de la requête. L'appelant sait ce que c'est, mais la méthode qui utilise le tableau ne sait pas combien ou quel type attendre. C'est à dire. Je ne peux pas changer la méthode en Read (nom: string; age: integer).
- Les paramètres ne sont pas nécessairement utilisés dans le même ordre que les valeurs spécifiées dans le tableau de const. Dans l'exemple, keyFields est spécifié en tant que "Name, Age" mais la requête utilise Age before Name. Cela signifie que Params [i] .Value: = keyValues [i] ne fonctionnera pas. Je pense que VarRecToVariant serait encore nécessaire de toute façon, ce que j'essaie d'éviter).
Le ruban adhésif n'est jamais très joli, et c'est essentiellement ce que vous faites, en joignant deux systèmes différents. Il y aura toujours un décalage d'impédance. –
BTW, il existe déjà une fonction très similaire dans la VCL: ConvertToVariant dans l'unité MxCommon. –
@TOndrej, je ne connaissais pas ConvertToVariant, merci de le mentionner. – WileCau