¿Existe una forma estándar de convertir entre TVarRec y los valores de Variant?Cómo convertir entre TVarRec y Variant?
Quiero analizar una 'matriz de const' y usar los valores para rellenar los parámetros en un TMSQuery. Para hacer esto, estoy usando una lista de nombres de columna (generados a partir de TMSQuery.KeyFields) y haciendo coincidir los valores de la matriz con los nombres de columna en KeyFields (por posición), y luego usando el nombre de la columna para establecer el parámetro correspondiente usando ParamByName .
El código siguiente es lo que he encontrado, pero VarRecToVariant no parece muy elegante. ¿Hay una mejor solución?
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;
Notas:
- Los valores de la matriz const dependen de los parámetros de la consulta. La persona que llama sabe cuáles son, pero el método que utiliza la matriz no sabe cuántos o qué tipo esperar. Es decir. No puedo cambiar el método para Leer (nombre: cadena; edad: número entero).
- Los parámetros no se usan necesariamente en el mismo orden en que se especifican los valores en la matriz de const. En el ejemplo, keyFields se especifica como "Nombre, Edad", pero la consulta usa Age before Name. Esto significa que los parámetros [i] .Value: = keyValues [i] no funcionarán. Creo que todavía necesitaría VarRecToVariant, lo cual estoy tratando de evitar).
La cinta para conductos nunca es muy bonita, y eso es básicamente lo que está haciendo, uniendo dos sistemas diferentes. Siempre habrá algún error de impedancia. –
Por cierto, ya hay una función muy similar en el VCL: ConvertToVariant en la unidad MxCommon. –
@TOndrej, no sabía acerca de ConvertToVariant, gracias por mencionarlo. – WileCau