2010-09-17 9 views
7

Czy istnieje standardowy sposób konwersji wartości TVarRec i Variant?Jak przekonwertować między TVarRec i Variant?

Chcę przeanalizować "tablicę stałych" i użyć tych wartości do zapełnienia parametrów w TMSQuery. Aby to zrobić, używam listy nazw kolumn (generowanych z TMSQuery.KeyFields) i dopasowywania wartości w tablicy do nazw kolumn w polach KeyField (według pozycji), a następnie używania nazwy kolumny do ustawienia odpowiedniego parametru za pomocą ParamByName .

Poniższy kod jest tym, co wymyśliłem, ale VarRecToVariant nie wydaje się bardzo elegancki. Czy istnieje lepsze rozwiązanie?

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; 

Uwagi:

  • Wartości w tablicy const zależy od parametrów w zapytaniu. Dzwoniący wie, co to jest, ale metoda wykorzystująca tablicę nie wie, ile i jakiego typu oczekiwać. To znaczy. Nie mogę zmienić metody odczytu (nazwa: ciąg; wiek: liczba całkowita).
  • Parametry niekoniecznie są używane w tej samej kolejności, w której wartości są określone w tablicy stałej. W przykładzie keyFields są określone jako "Name, Age", ale zapytanie używa Age przed Name. Oznacza to, że Params [i] .Value: = keyValues ​​[i] nie będzie działać. Myślę, że VarRecToVariant i tak będzie nadal potrzebny, czego staram się unikać).
+0

Taśma klejąca nigdy nie jest bardzo ładna, a to w zasadzie to, co robisz, łącząc dwa różne systemy. Zawsze będzie jakieś niedopasowanie impedancji. –

+1

BTW, istnieje już bardzo podobna funkcja w VCL: ConvertToVariant w jednostce MxCommon. –

+0

@TOndrej, nie wiedziałem o ConvertToVariant, dziękuję za wzmiankę o tym. – WileCau

Odpowiedz

5

Wymień

procedure Read(keyValues: array of const); 

z

procedure Read(keyValues: array of Variant); 

Wtedy nie będzie trzeba konwertować TVarRec wariantu.

+0

dziękuję za boczne myślenie, którego potrzebowałem :) Byłem tak zagłębiony w szczegółach konwersji tablicy, o której nie myślałem, po prostu zmieniając typ tablicy. – WileCau

+2

+1 za myślenie nieszablonowe. –

+0

Variant nie może przechowywać wszystkiego, co potrafi TVarRec. –

Powiązane problemy