问题
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?
回答1:
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:
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;
来源:https://stackoverflow.com/questions/27120136/create-insert-function-of-any-record-type-in-delphi-xe7