LAST_INSERT_ID after restarting MySQL - mysql

I'm trying to retrieve the LAST_INSERT_ID by following statements after inserting a new record, it works fine.
SELECT LAST_INSERT_ID();
The problem
When Inserting a new record in table and restart MySQL Server and then trying to retrieve LAST_INSERT_ID, it gets 0 value!
LAST_INSERT_ID just works before restarting MySQL or rebooting system ?
Any help would be appreciated.

as stated in MySQL Docs,
The ID that was generated is maintained in the server on a per-connection basis. This means that the value returned by the function to a given client is the first AUTO_INCREMENT value generated for most recent statement affecting an AUTO_INCREMENT column by that client. This value cannot be affected by other clients, even if they generate AUTO_INCREMENT values of their own. This behavior ensures that each client can retrieve its own ID without concern for the activity of other clients, and without the need for locks or transactions.
Which means - after restart for your set of statements there is no statement affecting AUTO_INCREMENT value, so the value is undefined.

See this text in the LAST_INSERT_ID manual page:
The ID that was generated is maintained in the server on a per-connection basis.
If you restart the server, or disconnect and reconnect againg, then you are not using the same connection as when you did the insert, so that's why you get 0

As it was already stated based on MySQL Reference Manual: function_last-insert-id:
The ID that was generated is maintained in the server on a
per-connection basis. This means that the value returned by the function to a given client is the first AUTO_INCREMENT value generated for most recent statement affecting an AUTO_INCREMENT column by that client.
To get what you need, just make a new query:
SELECT MAX(ID) FROM ExampleTable;
in case you can't use LAST_INSERT_ID in the intended way.

Related

MySQL LAST_INSERT_ID Query

I've had a look at the official documentation but I'm still a bit confused.
Say I have a procedure and it runs and performs an insert and then I request LAST_INSERT_ID(), am I getting the last insert id from the insert just done by my instance of the procedure running or is it the last insert id on the table by any instance/session that's called the procedure?
For example say the last inserted record ID was 4 and I called the procedure and my insert would be id 5 but my insert fails will I get 4 being returned as the last insert id or a null/0 value?
That very link to the documentation page that you gave in the question has an answer:
The ID that was generated is maintained in the server on a
per-connection basis. This means that the value returned by the
function to a given client is the first AUTO_INCREMENT value generated
for most recent statement affecting an AUTO_INCREMENT column by that
client. This value cannot be affected by other clients, even if they
generate AUTO_INCREMENT values of their own. This behavior ensures
that each client can retrieve its own ID without concern for the
activity of other clients, and without the need for locks or
transactions.
So, there is no race condition from other clients. You need to request the LAST_INSERT_ID() in the same connection as INSERT to get correct result.
As for, what happens when transaction is rolled back, it is undefined:
If the previous statement returned an error, the value of
LAST_INSERT_ID() is undefined. For transactional tables, if the
statement is rolled back due to an error, the value of
LAST_INSERT_ID() is left undefined. For manual ROLLBACK, the value of
LAST_INSERT_ID() is not restored to that before the transaction; it
remains as it was at the point of the ROLLBACK.
The documentation you linked to says:
The ID that was generated is maintained in the server on a per-connection basis. This means that the value returned by the function to a given client is the first AUTO_INCREMENT value generated for most recent statement affecting an AUTO_INCREMENT column by that client. This value cannot be affected by other clients, even if they generate AUTO_INCREMENT values of their own.
This means you can safely rely on the value returned by LAST_INSERT_ID(). It is the most recent auto incremented value generated by the same instance of the code that calls LAST_INSERT_ID(). Of course, you have to call it right after the INSERT statement you want to get the value for, it cannot return the values generated by the second most recent INSERT statement or older.

Reset Auto_Increment on MySql via MSSQL? I'll even settle for Truncate

I have a MSSQL Server 2008 R2 system that updates various tables on various systems during a nightly process. I have a MySQL linked server that has an Auto_Increment on one of it's tables. This tables contents are deleted and replaced each night. This of course does not reset the increment. I have tried:
ALTER TABLE REMOTEMYSQL...[TableWithAI] AUTO_INCREMENT = 1
And I get:
Incorrect syntax near 'AUTO_INCREMENT'
I can successfully:
delete from REMOTEMYSQL...[TableWithAI]
But obviously that doesn't reset the increment on the MySQL side
I tried:
Truncate TABLE REMOTEMYSQL...[TableWithAI]
and I get:
Cannot find the object "TableWithAI" because it does not exist or you do not have permissions.
But the MySql user that is used in the link has full permissions. How can I ether delete the contents and zero the increment, or zero the increment by itself?
Assuming you have your MySQL already configured as a linked server, you can fire off non-query statements to linked servers with EXEC:
EXEC('ALTER TABLE TableWithAI AUTO_INCREMENT = 1') AT LinkedMySQLServerName;
I believe the query should be in MySQL syntax, but I'm not in a position to test from where I'm at.

Is it possible to get LAST_INSERT_ID() from different database?

Suppose, that we have 2 databases: a and b, and tables a.test1 and b.test2.
If I need to insert a row into table a.test1, and return LAST_INSERT_ID() to insert into b.test2, will LAST_INSERT_ID() return value from another database? Is it reliable?
I didn't find anything in the manual, but ##IDENTITY depends on client session, so it should be portable between two databases. Isn't it?
LAST_INSERT_ID() always gives you the id of the row inserted by the last INSERT statement you executed on the current connection, irrespective of what table (and what database!) that row went into.
From Mysql documentation:The ID that was generated is maintained in the server on a per-connection basis. This means that the value returned by the function to a given client is the first AUTO_INCREMENT value generated for most recent statement affecting an AUTO_INCREMENT column by that client. This value cannot be affected by other clients, even if they generate AUTO_INCREMENT values of their own. This behavior ensures that each client can retrieve its own ID without concern for the activity of other clients, and without the need for locks or transactions.
Inshort Both *LAST_INSERT_ID()* and *mysql_insert_id()* work as advertised i.e.: they will retrieve the last id inserted into any table during the current session/connection.

MySQL and PDO: Could PDO::lastInsertId theoretically fail?

I have been pondering on this for a while.
Consider a web application of huge proportions, where, let's say, millions of SQL queries are performed every second.
I run my code:
$q = $db->prepare('INSERT INTO Table
(First,Second,Third,Fourth)
VALUES (?,?,?,?)');
$q->execute(array($first,$second,$third,$fourth));
Then immediately after, I want to fetch the auto incremented ID of this last query:
$id = $db->lastInsertId();
Is it possible for lastInsertId to fail, i.e. fetch the ID of some SQL insert query that was executed between my two code blocks?
Secondary:
If it can fail, what would be the best way to plug this possible leak?
Would it be safer to create another SQL query to fetch the proper ID from the database, just to be sure?
It will always be safe provided that the PDO implementation is not doing something really bone-headed. The following is from the MySQL information on last_insert_id:
The ID that was generated is maintained in the server on a per-connection basis. This means that the value returned by the function to a given client is the first AUTO_INCREMENT value generated for most recent statement affecting an AUTO_INCREMENT column by that client. This value cannot be affected by other clients, even if they generate AUTO_INCREMENT values of their own. This behavior ensures that each client can retrieve its own ID without concern for the activity of other clients, and without the need for locks or transactions.
No. lastInsertId is per-connection, and doesn't require a request to the server - mysql always sends it back in its response packet.
So if the execute method doesn't throw an exception, then you are guaranteed to have the right value in lastInsertId.
It won't ever give you the insert ID of anything else, unless your query failed for some reason (e.g. invalid syntax) in which case it might give you the insert ID from the previous one on the same connection. But not anybody else's.

Is there any alternative to "last_update_ID()" for mySQL?

I am currently working on a big web project using ASP and MySQL.
When inserting into multiple tables I've been using last_update_ID(), but after some research I've found that that SQL statement isn't safe.
So. the problem:
I use two different computers, with different internet connections.
Both computers are logged onto the system I am currently building. I have made a page that prints the connection_id(), and last_update_id.
If I update any table with one of the computers the other one also gets that last_update_ID.
Both computers have the same connection_ID.
What can I do to get around this?
I don't want to (if it's not necessary) do a select statement after the first INSERT; to search for the row that I inserted, to get the correct ID of that row.
It's not my server I am using so I can't make any large changes of the database.
I guess that this problem occurs because the webpages use the same loginName & password to connect to the database, is that true?
Is there any other alternative to get the last update ID? that is totally safe..
I close every connection at the end of the asp page. but that doesn't change the connection_ID.
The connection ID is the for a few minutes even thou I open up different web pages on the server.
I believe the LAST_INSERT_ID() is correct for the current session. So each session receives it's own correct value. Either I don't understand your question or you think you have a problem but you don't.
I am not aware of any LAST_UPDATE_ID() function, on an update you can easily retrieve the updated rows by SELECTing them with the same WHERE clause (before the update)?
reference: http://dev.mysql.com/doc/refman/5.0/en/getting-unique-id.html
For LAST_INSERT_ID(), the most
recently generated ID is maintained in
the server on a per-connection basis.
It is not changed by another client.
It is not even changed if you update
another AUTO_INCREMENT column with a
nonmagic value (that is, a value that
is not NULL and not 0). Using
LAST_INSERT_ID() and AUTO_INCREMENT
columns simultaneously from multiple
clients is perfectly valid. Each
client will receive the last inserted
ID for the last statement that
client executed.
If you want to retrieve the LAST_INSERT_ID from an INSERT query with an ON DUPLICATE KEY UPDATE clause, you can also use the LAST_INSERT_ID() function to retrieve the value of the AUTO_INCREMENT column that was updated:
reference: http://dev.mysql.com/doc/refman/5.0/en/insert-on-duplicate.html
If a table contains an AUTO_INCREMENT
column and INSERT ... UPDATE inserts a
row, the LAST_INSERT_ID() function
returns the AUTO_INCREMENT value. If
the statement updates a row instead,
LAST_INSERT_ID() is not meaningful.
However, you can work around this by
using LAST_INSERT_ID(expr). Suppose
that id is the AUTO_INCREMENT column.
To make LAST_INSERT_ID() meaningful
for updates, insert rows as follows:
INSERT INTO table (a,b,c) VALUES (1,2,3)
ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), c=3;
Your server appears to have connection pooling turned on. What this means is that the database connection is held open after a script finishes, and the next script that comes along uses it, and thus can see any variables that were set on that connection, including LAST_INSERT_ID().
What can't happen is two script instances sharing a connection at the same time. Thus, if your server is busy enough to need to run two script instances at exactly the same time, it will simply create a second database connection, with its own separate LAST_INSERT_ID() variable, and won't interfere with the first.
In short, as long as the INSERT and the LAST_INSER_ID() request happen within the same script (and you don't somehow close the database connection between them), they're completely safe, as your script has exclusive use of that connection.