If the ID
's are auto incremented fields then the following would work:
SELECT TOP 1 ID FROM tbl ORDER BY ID DESC
Question
I have a MS Access front end and a MySQL back end connected through ODBC.
I checked online, and there are lots of people who have the same problem but I still couldn't find a proper answer. I checked stackoverflow and also official documentation: http://dev.mysql.com/doc/connector-odbc/en/connector-odbc-usagenotes-functionality-last-insert-id.html
SELECT LAST_INSERT_ID();
on access simply returns undefined function last_insert_id()
When using: SELECT * FROM tbl WHERE auto IS NULL;
I replaced tbl for my table_name and auto for my tableID (the PK of the table), and it says: The setting you entered isn't valid for this property
. Is there any way to get the last ID inserted? or should I give up and find another way to get that ID?
Thanks
Solution 4
If the ID
's are auto incremented fields then the following would work:
SELECT TOP 1 ID FROM tbl ORDER BY ID DESC
OTHER TIPS
It depends on how the record insert occurs.
If you using a recordset, then this will work:
Dim rstRec As DAO.Recordset
Dim lngNewID As Long
Set restrec = CurrentDb.OpenRecordset("dbo_customers3", dbOpenDynaset, dbSeeChanges)
rstRec.AddNew
rstRec!FirstName = "Albert"
rstRec.Update
rstRec.Bookmark = rstRec.LastModified
lngNewID = rstRec!ID
rstRec.Close
So for recordsets, you have to use a bookmark (since update will bounce the record pointer off the record just inserterd - this is not occur for editRecord)
If you are using SQL INSERT statements, then for MySQL the recommend approach is your original given syntax. Of course you cannot not use Access sytanx. The simple change is you are using MySQL syntax and thus you need to make the query in question pass-through (and ensure set records = yes (which should be the case of converting a query to pass-though).
It is a VERY bad idea to use SELECT TOP on the database if you have multiple users.
Thus, you place the following statement in a pass-though query.
SELECT LAST_INSERT_ID();
Then in VBA code, you can go:
Dim strSQL As String
Dim lngNewID As Long
strSQL = "INSERT into dbo_customers3 (FirstName, LastName) VALUES ('Albert', 'Kallal')"
CurrentDb.Execute strSQL
lngNewID = CurrentDb.OpenRecordset("QryPassReturn")(0)
The above will “return” the lastID to your session regardless if other users are inserting into this table and EVEN if inserts occur by others "during" the time between the above two statements.
The "pass-through query" solution can be done elegantly. It just requires passing a Connection
object around and ensuring at least the insert
and the last_insert_id()
queries are performed on the same connection. This will also improve performance by avoiding the linked tables on the default connection.
Here is my example.
Dim Conct As ADODB.Connection
Dim Query As ADODB.Command
Dim Result As ADODB.Recordset
Dim myid As Long
Set Conct = New ADODB.Connection
Set Query = New ADODB.Command
Conct.ConnectionString = "ODBC;DRIVER=MySQL ODBC 8.0 Unicode Driver;DSN=my-custom-dsn"
Conct.Open
With Query
Set .ActiveConnection = Conct
.CommandText = "INSERT INTO mytable (col1, col2) VALUES ('test', 'test')"
.Execute
.CommandText = "SELECT LAST_INSERT_ID()"
Set Result = .Execute
End With
myid = Result(0)
Debug.Print myid
if another user insert record at same time it dosnt work corrcetly.best way is using stored prosedure that return id for add new record (in multi user app). for sql use stored procedure.use this way
CREATE PROCEDURE dbo.AddAsset
@Name VARCHAR(500),
@URL VARCHAR(2000),
@new_identity INT = NULL OUTPUT
AS
BEGIN
SET NOCOUNT ON;
INSERT dbo.Assets(Name, URL) SELECT @Name, @URL;
SET @new_identity = SCOPE_IDENTITY();
END
GO
then use this sp in front end