OK, so here is my scenario - you may disagree with what I'm attempting to do but I have my reasons.
The user is able to upload various information to the database, I also want them to be able to upload a picture at the same time. Now for various reasons I want to store the image with the file name the ID number of the record I'm adding (I have an ID column as the primary which auto-increments). Obviously I would have to store the file extension in the database too.
Now is there a way I can add the record and then know what ID was set so that I can save the image? I don't want to query and select the highest ID as that could go wrong if two people were to submit the form at the same time.
Any ideas?
LAST_INSERT_ID() will give you the ID that was auto-generated:
... returns a BIGINT (64-bit) value representing the first
automatically generated value that was set for an AUTO_INCREMENT
column by the most recently executed INSERT statement to affect such
a column. For example, after inserting a row that generates an
AUTO_INCREMENT value, you can get the value like this:
mysql> SELECT LAST_INSERT_ID();
-> 195
After running an insert in PHP, you can get the AUTO_INCREMENT ID from $mysqli->insert_id (where $mysqli is a MySQLi connection object), $pdo->lastInsertId (where $pdo is a PDO connection object), or mysql_insert_id() (if you're still using MySQL, which you shouldn't be) without having to run another query.
Related
According to the PHP documentation, mysql_insert_id takes the last inserted id from the mysql table.
My question is, if I have a website that inserts more than 2 rows per second to the DB, can I use the mysql_insert_id and get the correct ID I am referring to in the INSERT query a line before?
From the MySQL manual:
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.
Short version: it is safe to use.
mysql_insert_id gives you the insert id of the most recent INSERT statement on the connection you give it.
If you call this immediatly after your insert, on the same mysql connection, you get the inserted id matching that insert statement, independantly of any other inserts going on in the mean time.
According to the PHP documentation, mysql_insert_id takes the last inserted id from the mysql table.
My question is, if I have a website that inserts more than 2 rows per second to the DB, can I use the mysql_insert_id and get the correct ID I am referring to in the INSERT query a line before?
From the MySQL manual:
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.
Short version: it is safe to use.
mysql_insert_id gives you the insert id of the most recent INSERT statement on the connection you give it.
If you call this immediatly after your insert, on the same mysql connection, you get the inserted id matching that insert statement, independantly of any other inserts going on in the mean time.
I'm using an INSERT ON DUPLICATE KEY statement for my website. It's for creating news items, so I figured I could use the same MySQL command for both creating and updating news items.
However, when I use the following:
INSERT INTO table (id,title,content) VALUES(NULL,"Test","Test");
Instead of creating a new auto increment value it throws an error. However, the command works on my main development server. But not on my laptop. Both versions of MySQL are the same, the only difference being MySQL was installed manually on my server, and with WAMP on my laptop.
Are there any MySQL Variables that could be causing this?
I would suggest using INSERT INTO table (title,content) VALUES("Test","Test");
This will create a new row in the table with a new incremented ID.
Managed to solve it as best as I can.
I checked my code and found that when I inserted the empty POST'd ID was wrapping it in quotations. I've now changed it so that it puts NULL without quotations. So my query should now look like:
INSERT INTO table (id,title,content) VALUES(NULL,"test","Test")
ON DUPLICATE KEY UPDATE title=VALUES(title), content=VALUES(content);
That now works.
I think you should make query like this,
INSERT INTO table (title,content) VALUES("Test","Test");
If it still doesn't work then check if id column is set as auto-increment or not.
Let's say I have a MySQL table and a table has a row with id and it has auto_incremented. Let's say via MySQL query and PHP, I add a row. The first row has id of 1. Then I manually add a second row (via phpmyadmin) with the id of 2. If I do a third MySQL insert via PHP... what would the id be for the third row... 2 or 3?
Question is... does auto_increment take into account manual inputs?
does auto_increment take into account manual inputs?
Yes it does. But I hope you do not really type in the ID manually, right? :-) Just leave this field alone when inserting (manually or programatically), MySQL will take care of it for you.
MySQL does accept manual inputs, and it WILL try to set the value you offer. If the value does not exist, it gets inserted, else you get a duplicate key error.
Put a value when you want to decide a value yourself (for example,
you deleted a line, and now want the exact same line in the table).
Put NULL or leave the column out of the insert to let the database
use the auto-increment.
Just a hint: when your application is choosing the values to put for an autoincrement value, you are probably doing something wrong.
I'm trying to keep the database tables for a project I'm working on nice and normalized, but I've run into a problem. I'm trying to figure out how I can insert a row into a table and then find out what the value of the auto_incremented id column was set to so that I can insert additional data into another table. I know there are functions such as mysql_insert_id which "get the ID generated from the previous INSERT operation". However, if I'm not mistaken mysql_insert_id just returns the ID of the very last operation. So, if the site has enough traffic this wouldn't necessarily return the ID of the query you want since another query could have been run between when you inserted the row and look for the ID. Is this understanding of mysql_insert_id correct? Any suggestions on how to do this are greatly appreciated. Thanks.
LAST_INSERT_ID() has session scope.
It will return the identity value inserted in the current session.
If you don't insert any rows between INSERT and LAST_INSERT_ID, then it will work all right.
Note though that for multiple value inserts, it will return the identity of the first row inserted, not the last one:
INSERT
INTO mytable (identity_column)
VALUES (NULL)
SELECT LAST_INSERT_ID()
--
1
INSERT
INTO mytable (identity_column)
VALUES (NULL), (NULL)
/* This inserts rows 2 and 3 */
SELECT LAST_INSERT_ID()
--
2
/* But this returns 2, not 3 */
You could:
A. Assume that won't be a problem and use mysql_insert_id
or
B. Include a timestamp in the row and retrieve the last inserted ID before inserting into another table.
The general solution to this is to do one of two things:
Create a procedural query that does the insert and then retrieves the last inserted id (using, ie. LAST_INSERT_ID()) and returns it as output from the query.
Do the insert, do another insert where the id value is something like (select myid from table where somecolumnval='val')
2b. Or make the select explicit and standalone, and then do the other inserts using that value.
The disadvantage to the first is that you have to write a proc for each of these cases. The disadvantage to the second is that some db engines don't accept that, and it clutters your code, and can be slow if you have to do a where on multiple columns.
This assumes that there may be inserts between your calls that you have no control over. If you have explicit control, one of the other solutions above is probably better.