Create insert function of any record type in Delphi XE7?

1k Views Asked by At

I have an record type for each Table in SQL Server. So when I want to insert (or update) a record on table I define a function to do so. Each field in delphi record has equivalent field in SQL table (with exact same name an type). It is too interesting to me to write a function to do this ( for example Inserting) for all record types using Retti. I mean a function that have a parameter for receive any record and creates insert query. I searched a lot and asked this question but finally not find the solution. Can anyone guide me to solution. I mean how to pass any record (any type) into a function as parameter?

2

There are 2 best solutions below

0
On BEST ANSWER

Try something like this:

type
  TSqlHlpr<T: record> = class
  public
    class procedure Insert(const Rec: T);
  end;

class procedure TSqlHlpr<T>.Insert(const Rec: T);
var
  Ctx: TRttiContext;
  RecType: TRttiType;
  TableName: String;
  Field: TRttiField;
  Value: TValue;
  FieldValues: TDictionary<String, TValue>;
  FieldPair: TPair<String, TValue>;
begin
  FieldValues := TDictionary<String, TValue>.Create;
  try
    Ctx := TRttiContext.Create;
    try
      RecType := Ctx.GetType(TypeInfo(T));

      TableName := RecType.Name;
      // massage TableName as needed to match the DB...

      for Field in RecType.GetFields do
      begin
        Value := Field.GetValue(@Rec);
        FieldValues.Add(Field.Name, Value);
      end;
    finally
      Ctx.Free;
    end;

    for FieldPair in FieldValues do
    begin
      // insert FieldPair.Value into FieldPair.Key column of TableName as needed...
    end;
  finally
    FieldValues.Free;
  end;
end;

type
  TMyTable = record
    // table fields here...
  end;

var
  rec: TMyTable;
begin
  // fill rec as needed...
  TSqlHlpr<TMyTable>.Insert(rec);
end;
2
On

OK I found my answer. Yes it is possible and so simple using untyped parameters like this :

procedure CreateSQLInsert(var Data)
begin
  // and do whatever with your any type record using Retti
end;