Search code examples
delphiadonull-object-pattern

Delphi10 ObjectPascal: how do I just get to access the fields in a ADODataSet single record


So really happy with connecting to the DB and all that. My Grid object is fine and showing all records etc. Really happy with SQL. And the concept "DBs are all about sets"

My issue is:

I create an ADO query or dataset object where the SQL returns one record only. I know I have done that by interrogating MyFrame.ADOQuery1.RecordCount (it returns 1) But how do I then get access to the record fields simply ?

I want to write

MyRecord[] := MyFrame.ADOQuery1.ReturnRecord; // could be current record as I know there is only one

Questions are : is there/can I create a var type I can use to read that record into ? And how do I do that ? Kinda thought there would be a ADOQuery method that would return a record into an array of the same type (though not sure how to specify that type) (emphasises to show reserved words versus natural english)

Anyway, I have been trying to do this for days and clearly missing something. Help, as ever, appreciated.


Solution

  • All Delphi dataset types are descended from TDataSet. This implements a data access model in which the dataset has a logical "cursor" which, if the dataset contains any data rows at all, is positioned on exactly one data row, initially the first one immediately after the dataset is opened. The Fields property of the dataset, or its FieldByName method can be used to access the field values of the data row which the dataset curor is pointing to.

    Navigating or traversing the dataset is a simple matter of using one of the dataset's navigation methods (e.g. Next, Prior, MoveBy and Locate). For example

    DataSet.First;
    while not DataSet.Eof do begin
      Memo1.Lines.Add(DataSet.FieldByName('Country').AsString);
      DataSet.Next;
    end;
    

    If you've followed what I've said above, it should be obvious what this code does - if not, ask.

    For your "age" example, just do this:

    var
      Age : Integer;
    [...]
      Age := DataSet.FieldByName('Age').AsInteger;
    
    • it's as simple as that.

    It is generally not a good idea to try to use a record as you seem to be envisaging to store a copy of the current data row's contents. It makes an unnecessary and avoidable copy of the row data.

    Equally, using an array to store the current row's data is unnecessary and not really the "Delphi" way of working with dataset rows, it's more like the sort of thing you might (be forced to) do in VB or similar. It has little or no bebifit with Delphi datasets.