2010-09-17 14 views
7

Esiste un modo standard per convertire tra i valori di TVarRec e Variant?Come convertire tra TVarRec e Variant?

Voglio analizzare un 'array di const' e utilizzare i valori per popolare i parametri in un TMSQuery. Per fare questo sto usando un elenco di nomi di colonne (generati da TMSQuery.KeyFields), e facendo corrispondere i valori nell'array con i nomi delle colonne in KeyFields (per posizione), quindi usando il nome della colonna per impostare il parametro corrispondente usando ParamByName .

Il codice seguente è quello che ho trovato, ma VarRecToVariant non sembra molto elegante. C'è una soluzione migliore?

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; 

Note:

  • I valori nella matrice di const dipendono dai parametri della query. Il chiamante sa cosa sono, ma il metodo che usa l'array non sa quanti o quale tipo aspettarsi. Cioè Non riesco a cambiare il metodo in Read (name: string; age: integer).
  • I parametri non sono necessariamente utilizzati nello stesso ordine in cui i valori sono specificati nell'array di const. Nell'esempio, i campi chiave sono specificati come "Nome, Età" ma la query utilizza Età prima del nome. Ciò significa che Params [i] .Value: = keyValues ​​[i] non funzionerà. Penso che VarRecToVariant sia comunque necessario, cosa che sto cercando di evitare).
+0

Il nastro adesivo non è mai molto bello, ed è essenzialmente quello che stai facendo, unendo due sistemi diversi. Ci sarà sempre qualche disallineamento di impedenza. –

+1

BTW, c'è già una funzione molto simile nel VCL: ConvertToVariant nell'unità MxCommon. –

+0

@TOndrej, non sapevo di ConvertToVariant, grazie per averlo menzionato. – WileCau

risposta

5

Sostituire

procedure Read(keyValues: array of const); 

con

procedure Read(keyValues: array of Variant); 

Allora non sarà necessario convertire TVarRec a Variant.

+0

grazie è il pensiero laterale di cui avevo bisogno :) Ero così impantanato nel dettaglio della conversione della matrice che non pensavo di cambiare semplicemente il tipo di array. – WileCau

+2

+1 per pensare fuori dagli schemi. –

+0

La variante non può contenere tutto ciò che può TVarRec. –

Problemi correlati