INSERT doesn't work when followed by SELECT LAST_INSERT_ID - mysql

There are a lot of questions about LAST_INSERT_ID()
In my case, issue is:
When INSERT is followed by SELECT LAST_INSERT_ID() there are no records being inserted
INSERT INTO sequences (state) VALUES (0);
select LAST_INSERT_ID();
>>> 80 // nothing is added to DB
INSERT on it's own works OK
INSERT INTO sequences (state) VALUES (0);
>>>
select LAST_INSERT_ID();
>>> 81 // row is inserted
For testing I am using SequelPro, DB is Amazon's RDS MySQL. Same issue happens when I use Python's MySQLdb module.
Ideally I want to insert row, get back ID of it for future identification and use.

You should run one query at a time. Most SQL interfaces don't allow multiple queries.
MySQL allows a single query to be terminated by ; but if there's any words following the ; (except for a comment), it's be a syntax error, which will make the whole request fail. So the INSERT won't run either.
MySQL does have a connection option to allow multi-query, but it's not active by default. See https://dev.mysql.com/doc/refman/8.0/en/c-api-multiple-queries.html
There's really no reason to use multi-query. Just run the SELECT LAST_INSERT_ID() as a separate query following the INSERT. As long as you use the same connection, it'll give you the right answer.

Related

MySQL UPDATE statement is throwing "Column count doesn't match value count" error

(NOTE: I know this is an error that's commonly asked about, but most of the time, the issue is in an INSERT statement. I couldn't find a question on this website where this error happened during an UPDATE.)
I have a table in MySQL (InnoDB / v. 5.7.19) called RESULTS which has, among others, two columns called TYPE and STATUS. Both are of type ENUM, with PASS, FAIL and IGNORE being the supported values in both. I'm trying to run this UPDATE statement on that table, using Workbench (also tried the same directly on the DB machine, using the mysql command):
update `RESULTS` set `TYPE`='IGNORE' where `STATUS`='IGNORE';
I'm getting this error:
Error Code: 1136. Column count doesn't match value count at row 1
Changing the single quotes to double quotes didn't help. I'm able to run this query successfully:
select count(`TYPE`) from `RESULTS` where `STATUS`='IGNORE';
I'm probably making a silly mistake here, but can anyone point out what's wrong with the UPDATE statement?
As requested I am posting it as an answer.
The error basically is self-explanatory like performing an operation on set of attributes but the values provided in the query are not enough. But in your case, you are performing an update operation with all attributes and their values and still, this error appears it may be a case that there is some trigger is registered for this table probably on before/after the event, If that is the case you need to update or remove that trigger if no needed.

MYsql - Get insert id - sql

I want to execute a query that insert the insert id to one of the colums
And I want to know how to get the insert id
I read this answer Get inserted id from mysql insert procedure
but its talk about how to get the insert id after the query, And I want to get it when I do the query
I try to do:
$stmt = $db->prepare("INSERT INTO `files` (`name`, `fname`) VALUES (?, LAST_INSERT_ID() + ?)") or die($db->error);
$stmt->bind_param('ss', $name, $uniqid);
But its dosent work, I always get 56, also the contcat dosent work, what I need to do?
It is simply easier and better to save it after the insert. It is also highly unlikely you will get the correct id before the actual insert happens.
The most reliable way would be to use transactions.
Start a transaction
Insert the row
Update the insert id
Commit the transaction
The + is not a string concatenation operator in MySQL. Use CONCAT(string1, string2, ...).
In the wire protocol, mysql returns the same value as LAST_INSERT_ID() to the client after each query, unsolicited, and most libraries provide a way to access the most recently returned value. You didn't mention, but it looks like you're using mysqli in php, so you're looking for this:
$last_id = $db->insert_id;
It may look as if this is going to send a second query to ask the database for the id, but it isn't. It's returning the previously stored value.
http://php.net/manual/en/mysqli.insert-id.php

MYSQL last_insert_id() and concurrency

I have a simple MYSQL question. If I make a query that contains LAST_INSERT_ID() right after an INSERT QUERY running on a web page which has many concurrent users accessing other pages that perform INSERT operations would the value of LAST_INSERT_ID() be adulterated/corrupted?
No, it will return the insert id from the current connection. As long as your script hasn't made any other inserts, you will get the one you want.
Also be aware that this will only return a generated ID (e.g. an auto-increment). If you are creating your own ID's it won't return this to you.

executing queries together to gain efficiency

Presently I am using prepared statements to execute a query or an update on the database. Though pre-compiled(and hence fast) I think that it would be even more efficient if could have such an arrangement:
Scenario:
Suppose I have to insert 100 rows in a database table. I use prepare statements so I prepare a statement and send it to the database for execution. So each time the query is of the form:
insert into user values(....);
Now consider this situation when I have a query of the form
insert into user values (...), (...), ....,(...);
By this we can minimize table access and execute query in one go.
Is there any way that we can do this using prepared statements or such an arrangement where we can instruct database that execute next 100 updates together. By the way I am presently working on mysql
INSERT statements that use VALUES syntax can insert multiple rows. To
do this, include multiple lists of column values, each enclosed within
parentheses and separated by commas. Example:
INSERT INTO tbl_name (a,b,c) VALUES(1,2,3),(4,5,6),(7,8,9);
Try something like
st = con.createStatement();
st.addBatch("INSERT INTO tbl_name VALUES(1,2,3)");
st.addBatch("INSERT INTO tbl_name VALUES(4,5,6)");
st.addBatch("INSERT INTO tbl_name VALUES(7,8,9)");
st.executeBatch();
Any reason not to do it as a bulk insert operation?
There's probably a better way of doing it, but I simply write a "file" to /dev/shm then reference in a LOAD DATA INFILE statement, thus never hitting disk on the client machine.

Easy mysql question regarding primary keys and an insert

In mysql, how do I get the primary key used for an insert operation, when it is autoincrementing.
Basically, i want the new autoincremented value to be returned when the statement completes.
Thanks!
Your clarification comment says that you're interested in making sure that LAST_INSERT_ID() doesn't give the wrong result if another concurrent INSERT happens. Rest assured that it is safe to use LAST_INSERT_ID() regardless of other concurrent activity. LAST_INSERT_ID() returns only the most recent ID generated during the current session.
You can try it yourself:
Open two shell windows, run mysql
client in each and connect to
database.
Shell 1: INSERT into a table with an
AUTO_INCREMENT key.
Shell 1: SELECT LAST_INSERT_ID(),
see result.
Shell 2: INSERT into the same table.
Shell 2: SELECT LAST_INSERT_ID(),
see result different from shell 1.
Shell 1: SELECT LAST_INSERT_ID()
again, see a repeat of earlier
result.
If you think about it, this is the only way that makes sense. All databases that support auto-incrementing key mechanisms must act this way. If the result depends on a race condition with other clients possibly INSERTing concurrently, then there would be no dependable way to get the last inserted ID value in your current session.
MySQL's LAST_INSERT_ID()
The MySQL Docs describe the function: LAST_INSERT_ID()
[select max(primary_key_column_name) from table_name]
Ahhh not nessecarily. I am not an MySQL guy but there are specific way to get the last inserted id for the last completed action that are a little more robust than this. What if an insert has happened between you writing to the table and querying it? I know about because it stung me many moons ago (so yeah it does happen).
If all else fails read the manual: http://dev.mysql.com/doc/refman/5.0/en/getting-unique-id.html