[Lazarus] TSQLQuery: Getting autoincremented ID value after insert (MySQL)
silvioprog
silvioprog at gmail.com
Thu Nov 13 15:33:58 CET 2014
On Thu, Nov 13, 2014 at 11:07 AM, Reimar Grabowski <reimgrab at web.de> wrote:
> Hi,
>
> first of all I am new to using Lazarus/FPC for database communication.
> I have set up my database connection, transaction and queries via the
> Object Inspector and all is working as it should. But I have a little
> problem getting the PK value of a newly inserted record (the PK field is an
> auto-incremented one).
> Actually it's not really a problem, I just don't like the way I do it and
> found no better one.
>
> Here is some code:
>
> SQLQuery.Insert;
> SQLQuery.FieldByName('SomeField').AsString:=SomeValue;
> SQLQuery.FieldByName('AnotherField').AsString:=AnotherValue;
> ... (setting more fields)
> SQLQuery.Post;
> SQLQuery.ApplyUpdates;
> SQLTransaction.Commit;
> // Now the part I don't like
> SQLQuery.Close;
> SQLQuery.Params.ParamByName('SomeField').AsString:=SomeValue;
> SQLQuery.Params.ParamByName('AnotherField').AsString:=AnotherValue;
> ... (setting more params, the same as the fields in the insert)
> SQLQuery.Open;
> NewID:=SQLQuery.FieldByName('AutoIncrementedPrimaryKey').AsInteger;
>
> It seems to work but it's IMHO not very nice.
> Ideally I'd like to have TSQLQuery do it for me and offer me some property
> like SQLQuery.LastInsertID or something along those lines.
> Is there any way to get the new PK value without manually querying for the
> inserted record?
>
> BTW the wiki (http://wiki.freepascal.org/Working_With_TSQLQuery) mentions
> that you should send 0 for the ID and add an appropriate 'ON DUPLICATE KEY'
> phrase to your SQL. I did not do this. I just omitted the ID in my
> SQLQuery.InsertSQL and AFAICT it works flawlessly.
>
> R.
I use an own "TPreparedStatement" (equivalent to TSQLQuery prepared +
Params, but my structure does not uses TDataset) that I get the last
inserted ID with (pseudo codes):
[code]
uses
Core.SQL.PreparedStatement, ...
VStmt := TPreparedStatement<TMyObject>.Create;
ID := VStmt.Execute; // get last inserted ID instead of rowsaffected
[/code]
or:
[code]
VStmt := TPreparedStatement<TMyObject>.Create;
ID := VStmt.Execute.Values.ID; // get last inserted ID
[/code]
or:
[code]
uses
Core.SQL.ConnectionFactory, ...
PK := TConnectionFactory.GetInstance(Context).Insert(MyObject);
[/code]
or:
[code]
TConnectionFactory.GetInstance(Context).Insert(MyObject);
WriteLn('The generated ID is: ', MyObject.Id);
[/code]
or with on conflict:
[code]
TConnectionFactory.GetInstance(Context).UpdateWithOnConflict(MyObject,
TConnection.CONFLICT_REPLACE);
WriteLn('The generated or existing ID is: ', MyObject.Id);
[/code]
I'll send it soon to the Github. =)
--
Silvio Clécio
My public projects - github.com/silvioprog
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.lazarus-ide.org/pipermail/lazarus/attachments/20141113/f4c7a750/attachment-0003.html>
More information about the Lazarus
mailing list