2010-09-17 12 views
7

Có cách nào tiêu chuẩn để chuyển đổi giữa các giá trị TVarRec và Biến thể không?Làm thế nào để chuyển đổi giữa TVarRec và Biến thể?

Tôi muốn phân tích cú pháp 'mảng const' và sử dụng các giá trị để điền thông số vào TMSQuery. Để làm điều này tôi đang sử dụng một danh sách các tên cột (được tạo từ TMSQuery.KeyFields), và kết hợp các giá trị trong mảng với các tên cột trong KeyFields (theo vị trí), sau đó sử dụng tên cột để đặt tham số tương ứng bằng cách sử dụng ParamByName .

Mã dưới đây là những gì tôi đã đưa ra, nhưng VarRecToVariant không có vẻ rất thanh lịch. Có giải pháp nào tốt hơn không?

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; 

Ghi chú:

  • Các giá trị trong mảng const phụ thuộc vào các thông số trong truy vấn. Người gọi biết cái này là gì, nhưng phương thức sử dụng mảng không biết có bao nhiêu hoặc loại nào mong đợi. I E. Tôi không thể thay đổi phương thức thành Read (name: string; age: integer).
  • Các tham số không nhất thiết được sử dụng theo cùng thứ tự mà các giá trị được chỉ định trong mảng của const. Trong ví dụ, keyFields được chỉ định là "Tên, tuổi" nhưng truy vấn sử dụng Age before Name. Điều này có nghĩa là Params [i] .Value: = keyValues ​​[i] sẽ không hoạt động. Tôi nghĩ rằng VarRecToVariant vẫn sẽ cần thiết anyway, mà tôi đang cố gắng để tránh).
+0

Băng keo không bao giờ rất đẹp, và đó là những gì bạn đang làm, tham gia hai hệ thống khác nhau. Luôn luôn có một số trở kháng không phù hợp. –

+1

BTW, đã có một chức năng rất giống nhau trong VCL: ConvertToVariant trong đơn vị MxCommon. –

+0

@TOndrej, tôi không biết về ConvertToVariant, cảm ơn vì đã đề cập đến nó. – WileCau

Trả lời

5

Thay

procedure Read(keyValues: array of const); 

với

procedure Read(keyValues: array of Variant); 

Sau đó, bạn sẽ không cần phải chuyển đổi TVarRec để Ngôn ngữ địa phương.

+0

cảm ơn đó là suy nghĩ bên tôi cần :) Tôi đã rất bogged xuống trong các chi tiết chuyển đổi mảng tôi không nghĩ đến việc chỉ thay đổi loại mảng. – WileCau

+2

+1 để suy nghĩ bên ngoài hộp. –

+0

Biến thể không thể chứa mọi thứ mà TVarRec có thể. –

Các vấn đề liên quan