Jump to content
dormky

How can I extract a row's data from a TMyQuery object ?

Recommended Posts

I'd like to extract a row's data as an object from a TMyQuery, so that I can give it as an argument to a function. But I don't see anything that can achieve that in the doc.

For background, this is using MyAccess to grab from a MySQL DB.

 

Typically I'd like to have something like

MyQuery.First();
DataObject := MyQuery.CurrentData();
MyQuery.Next();
// DataObject still has the data from the previous row

 

Share this post


Link to post

To use the example as shown, DataObject would be a type that has an overloaded assignment (Assign) operator that accepted a TDataSet (or TFDQuery or whatever). In Assign you would copy the data you want to the members of DataObject.

 

https://docwiki.embarcadero.com/RADStudio/Alexandria/en/Operator_Overloading_(Delphi)#Declaring_Operator_Overloads

 

 

Edited by weirdo12

Share this post


Link to post
On 10/18/2023 at 12:01 PM, dormky said:

DataObject := MyQuery.CurrentData();

Are you looking for a mechanism that is general, and can be applied to many queries?

 

What is the expected lifecycle for the DataObject, use as discardable parameter only, or extend with more properties and methods and store in other data structures?

I assume you want type safety so that an int/float/date/string in the db is represented as an int/float/date/string in the DataObject?

 

The obvious choice is to create a custom class tailored to the query. Upside is performance and custom adaptation. Downside is that you need to implement a new class and handcraft the conversion for every query.

 

A more flexible, but less performant approach, would be to use RTTI to map DB Fields to DataObject properties. either into a class or into a record type.

Basically, you would use RTTI to examine the property in the DataObject and use the name to look it up in the query, and the type to make the appropriate copying.

 

However, the distinct needs you have would have to be explained in more detail before we could detail the appropriate solution.

Share this post


Link to post
On 10/18/2023 at 12:01 PM, dormky said:

I'd like to extract a row's data as an object from a TMyQuery, so that I can give it as an argument to a function.

I'm not sure if that is what you are after: Dataset Enumerator Reloaded. The current location for the unit described in that article is now on GitHub as part of my CmonLib library: https://github.com/UweRaabe/CmonLib/blob/main/source/Cmon.DataSetHelper.pas

 

The code allows to retrieve the current record of a dataset either as a record or a class.

 

The record example shown in the article requires the declaration of a record

type
  [DBFields(mapAuto)]
  TEmployee = record
    EmpNo: Integer;
    LastName: string;
    FirstName: string;
    PhoneExt: string;
    HireDate: TDateTime;
    Salary: Double;
  end;

With that you can retrieve the data of the current dataset record like this:

var
  Employee: TEmployee;
begin
  { Show the employee's name and the hire date. }
  Employee := QuEmployee.GetCurrentRec<TEmployee>;
  ShowMessage(Format('%s %s was hired on %s', 
      [Employee.FirstName, Employee.LastName, FormatDateTime('dddddd', Employee.HireDate)]));
end;

The article also has another example using a class instead of a record.

  • Like 3

Share this post


Link to post

DataSetHelper does indeed seem to be what I'm looking for ! Too bad I'm almost finished writing the RTTI solution described just above by Lars, which I suppose is what DataSetHelper is doing. Writing it myself was what i wanted to avoid, but alas. Since I've written tests for it I'll use my code, but thanks for coming though anyway 🙂

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×