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

Was it helpful?

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

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top