Val Petruchek

подписывайтесь, а то хуже будет!  

ПОДПИСЫВАЙТЕСЬ НА RSS

« Самодисциплина
Скрыть реферера (HTTP_REFERER) »

Получить ID после Insert

26.06.07 @ 02:51 — Programming, PHP, SQL

Задача: получить идентификатор только что добавленной в таблицу записи.
Необходимое условие: в таблице должно быть AUTO_INCREMENT поле.

Решение (MySQL): SELECT LAST_INSERT_ID();
Решение (PHP/MySQL): mysql_insert_id();
Решение (MsSQL): SELECT @@IDENTITY AS ID;

Замечания:

  1. Сбросить (поменять) значение Next Autoindex в MySQL: ALTER TABLE `table_name` AUTO_INCREMENT = 238;
  2. При выполнении INSERT запроса на добавление нескольких записей (insert into `table_name` (field1,…,fieldm) values (’value11′,…,’value1m’), …, (’valuen1′,…,’valuenm’);) MySQL в качестве LAST_INSERT_ID возвращает идентификатор первой вставленной записи, а не последней, как можно было бы предположить.
  3. В некоторых версиях MySQL был баг: при неуспешном выполнении команды INSERT IGNORE (если уникальный ключ уже существует и ничего не добавляется) LAST_INSERT_ID возвращает следующее доступное значение для авто-инкремента.
  4. Не использовать LAST_INSERT_ID, когда его надо использовать, нельзя. Вариант “быстренько пишем в базу и мгновенно делаем SELECT максимального значения авто-инкремента” ужасен и нестабилен.

11 Comments »

  1. Спасибо! Пригодилось =)

    Comment by ROM — 04.12.2007 @ 18:32

  2. пригодилось

    Comment by can3p — 15.02.2008 @ 11:00

  3. пиздец, как пригодилось.

    Comment by Дмитрий — 17.08.2009 @ 11:39

  4. Народ, а если 10-15 соединений. Ну т.е. 10-15 человек работают обновременно с базой. Есть огромная вероятность , что они друг за другом могут сделать инсерт и данные будут перепутаны.

    Comment by Люди — 08.09.2009 @ 08:48

  5. Именно поэтому надо использовать LAST_INSERT_ID, а не 4-ый вариант.

    Comment by Val Petruchek — 08.09.2009 @ 09:05

  6. Для MS SQL вместо @@IDENTITY лучше использовать SCOPE_IDENTITY(). Иначе первая же вставка внутри триггера приведёт к непонятным и трудновыявляемым ошибкам.

    Comment by Аннонимус — 11.09.2009 @ 11:10

  7. Лучший вариант - это
    select max(id) from table;

    Comment by varle — 12.08.2012 @ 15:09

  8. varle, ваш вариант — это лучший способ получить чужой свежеполученный ID. Никто не гарантирует, что между вашим insertом и selectом не влезет ещё один insert. Догадайтесь, чей ID вам вернёт ваш max(id)

    Comment by Val Petruchek — 12.08.2012 @ 16:49

  9. если делать вставку и select одной транзакцией, тогда можно)

    Comment by xgenteam — 06.01.2013 @ 19:02

  10. или нет?

    Comment by xgenteam — 06.01.2013 @ 19:03

  11. Для MS SQL.
    Как вариант, можно (в дополнение к “стандартному” автоинкрементному ключу) создать доп. поле (varchar).
    И идентифицировать (по GUID) строку по этому полю:

    create procedure [dbo].[Str_GUID]
    (
    @sGUID varchar(50) OUTPUT
    )
    AS
    BEGIN
    /*
    Вычислить GUID и вернуть его строковое представление (без разделителей)
    Пример:
    DECLARE @Sx varchar(50)
    Execute dbo.Str_GUID @Sx OUTPUT
    select @Sx, len(@Sx)
    */
    DECLARE @myid uniqueidentifier
    SET @myid = NEWID()
    set @sGUID=cast(@myid as varchar(50))
    set @sGUID=UPPER(rtrim(ltrim(REPLACE(@sGUID , ‘-’, ‘’))))
    RETURN
    END

    Comment by roamer — 21.05.2013 @ 17:35

RSS feed for comments on this post. TrackBack URI

Leave a comment

  
Реклама::

 
Реклама::