18

I know how LAST_INSERT_ID() works for auto incremented columns, but I cannot find a way to get the last id I inserted for a non auto incremented column.

Is there a way I can do that?

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
Guiness
  • 277
  • 1
  • 4
  • 9
  • 4
    If the ID is not auto-increment, then you have to supply it in your INSERT statement, so you already have it – Maxim Krizhanovsky Jan 05 '12 at 16:53
  • @Darhazer: ... potentially in another application, potentially on another machine, potentially on another network in another country....? – Lightness Races in Orbit Jan 05 '12 at 16:56
  • 3
    by the way LAST_INSERT_ID() works only for the session that inserted the record, it won't return anything from another network in another country :) – Maxim Krizhanovsky Jan 05 '12 at 17:02
  • What datatype are you using for you "id" and what values are you storing in it? You might be able to use `SELECT MAX(IdColumn) as LastId FROM table`. Who knows? :) – Stefan Jan 05 '12 at 17:36
  • Columns don't have IDs; records do. If you want some other column of the last inserted record, you can select it using LAST_INSERT_ID(). Or did you mean something else? – Scott Hunter Jan 05 '12 at 16:54
  • Thank you, Stefan. I Create ID's using UNIX_TIMESTAMP(NOW()) and didn't realize I could query for MAX(id) after creation. I'm not sure if this is guaranteed to be safe if there could be multiple simultaneous creations but for me there wont be. – Clox Jan 26 '17 at 15:14

8 Answers8

21

you can easily do that using the same LAST_INSERT_ID().

INSERT INTO thetable (id, value)
VALUES (LAST_INSERT_ID(126), 'some data');

SELECT LAST_INSERT_ID();  -- returns 126
newtover
  • 31,286
  • 11
  • 84
  • 89
2

I'm assuming you want the retrieve this last inserted id at some later point after inserting it, since if you need it right after inserting it you obviously would already know what the id is.

The only way you'll be able to get that is to have another column on the table that can indicate which row was last inserted, such as a timestamp or datetime column. If your ids are unique and increasing, you can just use that column. Then you just select 1 row ordered by that column in descending order.

For example

INSERT INTO my_table (id, timestamp) VALUES (123, NOW())

SELECT id FROM my_table ORDER BY timestamp DESC LIMIT 1

Edit: as per the comments below, you're much better off using an AUTO_INCREMENT column, though this column doesn't have to be the id column, you could add an auto-increment insert_order column of type Int and simply order by that.

Dan Simon
  • 12,891
  • 3
  • 49
  • 55
  • 1
    Works fine for _very_ small-scale applications with guaranteed <= 1 insertion per second. All you're doing here is reinventing `AUTO_INCREMENT`, but in an inferior way! – Lightness Races in Orbit Jan 05 '12 at 16:59
  • 2
    Keep in mind an auto-incrementing column is thread-safe. A timestamp is not. – Mike Christensen Jan 05 '12 at 17:00
  • 1
    You're absolutely right, I was just about to edit my post to explain that using an AUTO_INCREMENT column is better, even if it's not the same column as id. – Dan Simon Jan 05 '12 at 17:02
1

The easiest way I found to do this is to set a variable.

Unlike using LAST_INSERT_ID which only returns and INT this way you can use other unique identifiers.

SET @id = UUID();

INSERT INTO users (
  id
)
VALUES (
  @id
);

SELECT * FROM users WHERE id = @id;
jfgrissom
  • 592
  • 5
  • 13
1

I assume that you need the ID to find your just inserted row, rather to find the last inserted row. In a web application, you can never be sure that the last inserted row is the one you have just created.

You could use a GUID as id in this case. A GUID is usually stored as a string of length 36 or as a 16byte blob. The GUID can be created before inserting the row, and then can be stored while inserting the row.

Since the id is not auto incremented as you stated, you have to generate it anyway before inserting the row. The safest way to do this is to create a GUID which should be unique enough. Otherwise you would have to determine the last unused ID, what can be tricky and risky.

martinstoeckli
  • 23,430
  • 6
  • 56
  • 87
  • In most cases this is applicable solution. i.e generate your own identifier and supply it to the `INSERT` statement – SaidbakR Apr 08 '17 at 19:31
-1

If you want to get a custom last_inserted ID, you must implement a procedure that will make the insert statment on your DB. At the end, just print the ID and use the PHP (if PHP is your main script) sender to return the generated row.

EXAMPLE:

DROP PROCEDURE IF EXISTS insert_row;
DELIMITER $$

CREATE PROCEDURE insert_row(IN _row_id VARCHAR(255), IN _description VARCHAR(255))
BEGIN
    SET @last_inserted_id = _row_id;
    SET @sql = CONCAT("INSERT INTO test VALUES ('", _row_id, "','",_description,"')");
    PREPARE stmt FROM @sql;
    EXECUTE stmt;
    DEALLOCATE PREPARE stmt;
    SELECT @last_inserted_id AS LAST_INSERT_ID;
END;
$$

DELIMITER ;
#
#
#
#------- HOW TO USE IT ? ---------------
CALL insert_row('Test001','the first test line');
David Buck
  • 3,752
  • 35
  • 31
  • 35
-1

This worked for me in XAMPP

$qry = $con->query("INSERT INTO test_table(tbl_id, txt) VALUES(last_insert_id('15'), 'test value')");
print_r($con->insert_id);
Saeid Amini
  • 1,313
  • 5
  • 16
  • 26
-1

No.

There is no inherent ordering of relations, no "last-inserted record". This is why the AUTO_INCREMENT field exists, after all.

You'd have to look in logs or cache the value yourself inside your application.

Lightness Races in Orbit
  • 378,754
  • 76
  • 643
  • 1,055
-1

There's no way with mysql. But you can to do it programmatically. Without an auto-incrementing ID column there's no way for the database to know which records were inserted last.

One way to do is use such as a column containing timestamp or datetime values. and get id of latest value of tmestamp to get last inserted record