2010-09-17 15 views
7

¿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).
+0

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. –

+1

Por cierto, ya hay una función muy similar en el VCL: ConvertToVariant en la unidad MxCommon. –

+0

@TOndrej, no sabía acerca de ConvertToVariant, gracias por mencionarlo. – WileCau

Respuesta

5

Reemplazar

procedure Read(keyValues: array of const); 

con

procedure Read(keyValues: array of Variant); 

Entonces no tendrá que convertir TVarRec la variante.

+0

gracias ese es el pensamiento lateral que necesitaba :) Estaba tan empantanado en el detalle de convertir el arreglo que no pensé simplemente cambiando el tipo de matriz. – WileCau

+2

+1 para pensar fuera de la caja. –

+0

La variante no puede contener todo lo que TVarRec puede. –

Cuestiones relacionadas