Leonardo Mozachi Neto <moza...@netpar.com.br> wrote:
Quote
>How can I access (read/write) the field values of a table using a
>"record" structure?
>Note: the table and the record has the same structure.
>type
> Rec = record
> cod: integer;
> name: string [30];
> date: TdateTime;
> hour: TdateTime;
> end;
>Next, I assign values to a Rec type variable:
>var
> MyRecord : Rec;
>begin
>.....
>MyRecord.cod := 002;
>MyRecord.name := 'Sample Name';
>MyRecord.date := strToDate(now);
>MyRecord.hour:= strToTime(now);
>......
>Table1.??????????? := MyRecord; // <- how am I supposed to do this?
The trick is to not use a record in the first place. Object Pascal,
as in the form of Delphi gives you the ideal solution : Objects.
You see -- with your record-based approach... if you change the
database type (from or to a SQL-oriented database, which even have
different dialects or flavours which might make your storage method
different from one database to another)... And if you change the
fields in your record, then you will need to find and alter every
section of code that stores or reads your record.
Object orientation helps this...
And with Objects there are TWO ideal ways to do this :
Streaming -- You can "stream" the data from any object descending from
tPersistent to and from a stream (sorry -- that's redundant and poorly
worded).
Or you could just add a ReadRecord and WriteRecord method into your
object like (I realize that this looks more complicated... but it will
probably appeal to you)... :
Here is how you could use this :
MyRecord := tJustARecord.Create;
MyRecord.Name := 'Sample Name';
MyRecord.Date := StrToDate( Now );
MyRecord.Hour := SstrToTime( Now );
MyRecord.LinkToTable( Table1 );
MyRecord.WriteRecord;
*** That way, all you EVER need to change is the ReadRecord and
WriteRecord in the object itself should you decide to change the data
stored therein... and isn't that where it's most logical anyway?
TYPE
tJustARecord = CLASS
PRIVATE
fLinkedToTable : tTable;
PROCEDURE fSetLinkedToTable( Value : tTable );
PUBLIC
Cod : INTEGER;
Name : STRING[30]; { might want to reconsider }
{ typing this to a normal string }
Date : tDateTime;
Hour : tDateTime;
PROPERTY LinkedToTable : tTable READ fLinkedToTable
WRITE fSetLinkedToTable;
PROCEDURE LinkToTable( inTable : tTable );
PROCEDURE WriteRecord;
PROCEDURE ReadRecord;
END; {end of object def };
{ down to IMPLEMENTATION ... }
VAR MyRecord : tJustARecord;
*** Remember to do something like MyRecord := tJustARecord.Create;
before using this... Then you can use the Object just like your
record... OH! And don't forget to MyRecord.Free when you are done
with it.
PROCEDURE tJustARecord.fSetLinkedToTable( Value : tTable );
BEGIN
fLinkedToTable := Value;
END;
PROCEDURE tJustARecord.LinkToTable( inTable : tTable );
BEGIN
LinkedToTable := inTable;
END;
PROCEDURE tJustARecord.WriteRecord;
BEGIN
{ table MUST be in a writeable mode like INSERT, EDIT or APPEND }
WITH LinkedToTable DO
BEGIN
Table.FieldByName( 'Code' ).AsInteger := Cod;
Table.FieldByName( 'Name' ).AsString := Name;
Table.FieldByName( 'Date' ).AsDateTime := Date;
Table.FieldByName( 'Hour' ).AsDateTime := Hour;
END;
END;
PROCEDURE tJustARecord.ReadRecord;
BEGIN
WITH LinkedToTable DO
BEGIN
Cod := Table.FieldByName( 'Code' ).AsInteger;
Name := Table.FieldByName( 'Name' ).AsString;
Date := Table.FieldByName( 'Date' ).AsDateTime;
Hour := Table.FieldByName( 'Hour' ).AsDateTime;
END;
END;
The other way is writing to the record all at once to a Blob field.
The only problem with this method is that you are essentially
restricted from ever changing the data-structure. Of course, this
method will make future migration of data to another database rather
difficult, if not entirely impossible. Other problems are that you
cannot use the contents of that blob field for searches (like
searching for everyone with a Code of 5, and a Name like "Tim*").
But it you still want to do it, then use a tBlobStream and a Blob
field (column) in your table.
Tim...