Задача: получить идентификатор только что добавленной в таблицу записи.
Необходимое условие: в таблице должно быть AUTO_INCREMENT поле.
Решение (MySQL): SELECT LAST_INSERT_ID();
Решение (PHP/MySQL): mysql_insert_id();
Решение (MsSQL): SELECT @@IDENTITY AS ID;
Замечания:
- Сбросить (поменять) значение Next Autoindex в MySQL: ALTER TABLE `table_name` AUTO_INCREMENT = 238;
- При выполнении INSERT запроса на добавление нескольких записей (insert into `table_name` (field1,…,fieldm) values (’value11′,…,’value1m’), …, (’valuen1′,…,’valuenm’);) MySQL в качестве LAST_INSERT_ID возвращает идентификатор первой вставленной записи, а не последней, как можно было бы предположить.
- В некоторых версиях MySQL был баг: при неуспешном выполнении команды INSERT IGNORE (если уникальный ключ уже существует и ничего не добавляется) LAST_INSERT_ID возвращает следующее доступное значение для авто-инкремента.
- Не использовать LAST_INSERT_ID, когда его надо использовать, нельзя. Вариант “быстренько пишем в базу и мгновенно делаем SELECT максимального значения авто-инкремента” ужасен и нестабилен.
Спасибо! Пригодилось =)
Comment by ROM — 04.12.2007 @ 18:32
пригодилось
Comment by can3p — 15.02.2008 @ 11:00
пиздец, как пригодилось.
Comment by Дмитрий — 17.08.2009 @ 11:39
Народ, а если 10-15 соединений. Ну т.е. 10-15 человек работают обновременно с базой. Есть огромная вероятность , что они друг за другом могут сделать инсерт и данные будут перепутаны.
Comment by Люди — 08.09.2009 @ 08:48
Именно поэтому надо использовать LAST_INSERT_ID, а не 4-ый вариант.
Comment by Val Petruchek — 08.09.2009 @ 09:05
Для MS SQL вместо @@IDENTITY лучше использовать SCOPE_IDENTITY(). Иначе первая же вставка внутри триггера приведёт к непонятным и трудновыявляемым ошибкам.
Comment by Аннонимус — 11.09.2009 @ 11:10
Лучший вариант - это
select max(id) from table;
Comment by varle — 12.08.2012 @ 15:09
varle, ваш вариант — это лучший способ получить чужой свежеполученный ID. Никто не гарантирует, что между вашим insertом и selectом не влезет ещё один insert. Догадайтесь, чей ID вам вернёт ваш max(id)
Comment by Val Petruchek — 12.08.2012 @ 16:49
если делать вставку и select одной транзакцией, тогда можно)
Comment by xgenteam — 06.01.2013 @ 19:02
или нет?
Comment by xgenteam — 06.01.2013 @ 19:03
Для 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