How to get the id of an inserted row ON insert? - mysql

I would like to create a unique hash of an AUTO-INCREMENT field while inserting that row. Something like:
INSERT INTO `table` (`hash`,`salt`) VALUES (MD5(CONCAT(`id`,`salt`)),'1234789687');
Is it possible to use the AUTO-INCREMENTED id of the row WHILE I'm inserting? Or do I have to wait until it's inserted to grab it via PHP or something?

The short answer is no- it is not possible. If your db has low transaction volume, then concurrency may not be an issue to use something similar to select max() (susceptible to interference) : Can you access the auto increment value in MySQL within one statement?
I would follow the insert in php with an update
update `table`
set `hash` = MD5(CONCAT(`id`,`salt`))
where `id` = LAST_INSERT_ID();

I don't know for sure, but really doubt that this is possible. I see why you would want to thought...It's not so elegant to insert the row, then immediately update it.
I would consider if you really need to store the hash in the DB or if you can calculate it during the select:
SELECT MD5(CONCAT(id,salt)) FROM table WHERE ...

Related

How can I get a newly inserted auto increment value?

Say a table T with a PRIMARY KEY id, I set it to AUTO INCREMENT.
I need to get the newly INSERTED id value for other operation, however, since it's the only PRIMARY KEY and AUTO INCREMENT, I don't how to do it.
Another SELECT with all other values in WHERE is valid in theory, but it's too slow.
Any better ideas?
Should you be checking LAST_INSERT_ID() like
select LAST_INSERT_ID();
Does this not work?
select max(id) from T;
This will produce the last id without functions
SELECT id FROM t ORDER BY id DESC LIMIT 1
By the way .. You should get the id after your insert statement from any MySQL api
It obviously depends on what database engine you use.
If , like I suppose, We are speaking about MSSQL, a good practise is to return last id generated in the current transaction (or session). You could see this post for more info.
Anyway, you could calculate the max id, but whitout warranties if someone instert new row in the while.

MySQL - can I use the gonna-be insert_id in the actual insert query itself?

I've just got a situation where i need to duplicate the unique
(auto-incremented) id of each new row in another column. So I was
wondering, instead of doing it the old fashioned way:
Insert row
Get insert_id
Update row with the insert_id
Can I tell MySQL to use the same value to which the new id is going
to be set, as a value for another column?
Something along the line of this:
INSERT INTO my_table(unique_column, id_duplicate)
VALUES('value', GET_UNIQUE_ID_OF_THIS() )
There's no way to accomplish what you're trying to accomplish using an auto-increment column in a single query.
Try approaching it from the other direction. Let's say your auto-increment column is id and your other column is called other_id. You could set the other_id column to allow NULL and simply set its value to NULL for the initial insert.
Then, when you query the value, simply do something like this:
SELECT id, IFNULL(other_id, id) AS other_id FROM mytable
The net result is the same. If you have something against NULL, you could also use 0 as the default value since auto-increment values start at 1.

MySQL: retrieving the newest inserted data

After inserting new data into a table, I need to select some of the new data straight after, so I can use it for inserting into another table.
The only way I can think of doing this is using the 'datetime' field I have in my row, but how would I retrieve the latest date/time inserted.
INSERT statement with NOW() value for datetime
society_select = SELECT socID, creator, datetime FROM societies.society WHERE datetime='[..datetime is the newest...]';
Hope that makes sense. Thank you
There are a number of ways to do this.
Why not make use of a trigger for this?
When a trigger creates a record you can get the id's of the records inserted. You can then do a select and insert new values into the relevant table.
MYSQL has loads of resources on using triggers.
http://dev.mysql.com/doc/refman/5.0/en/triggers.html
Or you can get the number of rows affected then use this to get the required result set in a select statement.
Get the last inserted ID?
If you are inserting one row into the database at a time then you would be able to get the last inserted id from MYSQL. This will be the Primary Key value of the record you last inserted into the database.
You would basically do something like this in mysql:
SET #inserted_id = LAST_INSERT_ID();
Or in PHP you can use the function:
mysql_insert_id(&mysql);
http://dev.mysql.com/doc/refman/5.0/en/getting-unique-id.html
Sort the results by their datetime in descending order, and select the first of them.
society_select = SELECT socID, creator, datetime FROM societies.society ORDER BY datetime DESC LIMIT 1;
you can use this with an auto increment filed. after inserting data you can retrieve the list inserted id from the table. and use that id to get the latest record.
A trigger as suggested is an option. If you don't want to use that for some kind of reason you can:
Add an integer primary key with auto_increment as ID and sort it DESC (e.g. INT(11))
Sort descending on a timestamp column (ofcourse with an index on it)
Use a trigger after inserting the data. This is for sure the cleaner way.
Another option is to use a method like mysql_insert_id. Assumed that you use PHP. There are of course equivalent methods in other languages as well.
Sorting is not an option(if not wrapped smart in transaction) - If you have multiple writes and reads on the table this might end up pretty ugly.

prevent gaps in MySQL id field

I have a MySQL table with an auto incremement id field. When I delete a row and then insert a new row, The id of the row I deleted is skipped and the new gets an id of one greater than the previous row. Is there any way I can prevent this? I would like the new row to just replace the old one. Is there an important reason why this happens that I am missing?
The MySQL auto-increment function NEVER goes backward unless you force it to. And for a good reason. What if there was stray references to the missing records (logs, tables, etc...)?
You can force it by using this command:
ALTER TABLE tbl AUTO_INCREMENT = 1000;
Or, if you need to do it as part of the query:
LOCK TABLES tbl WRITE;
SELECT #id := MAX(id) FROM tbl;
INSERT INTO tbl SET id=#id, ...;
UNLOCK TABLES;
If you are using InnoDB, you could do this in a transaction instead...
Better to leave it be, however.
The definition of an autoincrement field is that every new row inserted is guaranteed to get a unique value. If you want to keep the old value then you must UPDATE the row instead of replacing it. If your design requires that autoincrement column values be contiguous then you will have to manage that yourself.
I'm sorry but I don't know the exact reason.
AFAIK you can't avoid that behavior unless you TRUNCATE the table or explicitly specify the id.

How to insert the value derived from AUTO_INCREMENT into another column in the same INSERT query?

I have an id column which is a primary key with AUTO_INCREMENT. I need the value that is generated to be inserted into the id column, as well as another column (which isn't set to AUTO_INCREMENT, and isnt unique.
Currently I use the mysqld_isnert_id() function to get the id, and simply run an update query after the insert, but I was wondering if I could do this without running the 2nd update query.
after insert Trigger?
If I recall correctly, the automatically generated ID isn't even created until after the insert has been performed. Your two query way is probably the only way without diving into perhaps a stored procedure.
You could define a trigger along the lines of:
delimiter //
CREATE TRIGGER upd_check AFTER INSERT ON mainTable
FOR EACH ROW
BEGIN
UPDATE dependingTable
SET dependingTable.column = NEW.id
END;//
delimiter ;
I am not exactly sure WHEN the AUTO_INCREMENT value is generated, but you could try the following, since if it works it'll save you an update (If the column you want the value replicated to is in the same row as the inserted row):
CREATE TRIGGER upd_check BEFORE INSERT ON mainTable
FOR EACH ROW
SET NEW.column = NEW.id
The only way I can see you doing it with a single query is to use the information schema. In the information schema there is a table called 'tables', there you access the column auto_increment. That contains the NEXT insert id for that table, you can access this via a nested select, just give the user used to connect to the database read access to that table. This will only work with innodb engines as far as I can tell as that way the nested select you'll do to populate the second id field will be part of the greater transaction of the insert.
That's what your query might look like:
INSERT INTO fooTable VALUES (0, (SELECT AUTO_INCREMENT FROM information_schema.TABLES));
Also if you're worried about read access and security issues, just remember this is the same info you can get by running a show table status. Speaking of which, I tried to see if you could project the show commands/queries via a select and you can't, which totally sucks, because that would have been a much cleaner solution.