LAST_INSERT_ID () MySQL


151

У мене є питання MySQL, який, на мою думку, повинен бути досить легким. Мені потрібно повернути ОСТАННІЙ ВСТАНОВИЙ ідентифікатор з table1, коли я запускаю наступний запит MySql:

INSERT INTO table1 (title,userid) VALUES ('test',1); 
INSERT INTO table2 (parentid,otherid,userid) VALUES (LAST_INSERT_ID(),4,1);
SELECT LAST_INSERT_ID();

Як ви можете зрозуміти, що поточний код просто поверне ОСТАННУ ІНСТРУМЕНТУ ідентифікатора table2 замість table1, як я можу отримати ідентифікатор з table1, навіть якщо я вставляю в table2 між?

Відповіді:


248

Ви можете зберігати останній ідентифікатор вставки у змінній:

INSERT INTO table1 (title,userid) VALUES ('test', 1); 
SET @last_id_in_table1 = LAST_INSERT_ID();
INSERT INTO table2 (parentid,otherid,userid) VALUES (@last_id_in_table1, 4, 1);    

Або отримати таблицю max id frm1

INSERT INTO table1 (title,userid) VALUES ('test', 1); 
INSERT INTO table2 (parentid,otherid,userid) VALUES (LAST_INSERT_ID(), 4, 1); 
SELECT MAX(id) FROM table1;   

5
Дякую! Я не працював спочатку, коли я використовував asp.net з MySQL, і мені потрібно було додати дозвол змінних користувачів = True до рядка з'єднання, щоб дозволити змінні.
Мартін

114
max не є хорошою ідеєю, оскільки ви могли програти гонку з іншим вставкою.
Роб Старлінг

5
@RobStarling я повністю згоден, але у випадку, якщо комусь це абсолютно потрібно; використовувати транзакцію з належним рівнем ізоляції.
Aidiakapi

8
що робити, якщо 2 ВСТАВКИ відбудуться одночасно або одна перед одною?
FosAvance

32
@FosAvance LAST_INSERT_ID () є з'єднання конкретних посилань
Gun2sh

18

Оскільки ви фактично зберігали попередній LAST_INSERT_ID () у другій таблиці, ви можете отримати його звідти:

INSERT INTO table1 (title,userid) VALUES ('test',1); 
INSERT INTO table2 (parentid,otherid,userid) VALUES (LAST_INSERT_ID(),4,1);
SELECT parentid FROM table2 WHERE id = LAST_INSERT_ID();

13

Це дає змогу вставляти рядок у 2 різні таблиці і створювати посилання на обидві таблиці.

START TRANSACTION;
INSERT INTO accounttable(account_username) 
    VALUES('AnAccountName');
INSERT INTO profiletable(profile_account_id) 
    VALUES ((SELECT account_id FROM accounttable WHERE account_username='AnAccountName'));
    SET @profile_id = LAST_INSERT_ID(); 
UPDATE accounttable SET `account_profile_id` = @profile_id;
COMMIT;

1
Хороший знімок угоди.
Курт Ван ден Бранден

1
Але: доступний лише на InnoDB.
рейзерле

4

У мене була така ж проблема в баші, і я роблю щось подібне:

mysql -D "dbname" -e "insert into table1 (myvalue) values ('${foo}');"

що чудово працює :-) Але

mysql -D "dbname" -e "insert into table1 (myvalue) values ('${foo}');set @last_insert_id = LAST_INSERT_ID();"
mysql -D "dbname" -e "insert into table2 (id_tab1) values (@last_insert_id);"

не працюють. Тому що після першої команди оболонка вийде з mysql і знову ввійде для другої команди, і тоді змінна @last_insert_id більше не встановлена. Моє рішення:

lastinsertid=$(mysql -B -N -D "dbname" -e "insert into table1 (myvalue) values ('${foo}');select LAST_INSERT_ID();")
mysql -D "dbname" -e "insert into table2 (id_tab1) values (${lastinsertid});"

Можливо, хтось шукає рішення баш :-)


LAST_INSERT_IDдоступний лише для активного з'єднання. #mysq-командування підключення для кожної команди. Ви можете підключитися з mysqlкомандою до сервера і вставити свої запити, або ви можете створити текстовий файл, і ви mysqlкоманду з переспрямуванням з файлу txt akamysql [connection option] < txt.file
raserle

1

У нас є лише одна особа, яка вводить записи, тому я виконую наступний запит одразу після вставки:

$result = $conn->query("SELECT * FROM corex ORDER BY id DESC LIMIT 1");

while ($row = $result->fetch_assoc()) {

            $id = $row['id'];

}

Це отримує останній ідентифікатор з бази даних.


1
Мені довелося навести дійсний приклад, тому я використовував той, який я використовую. Якби я робив це в C, ви, напевно, поскаржилися б "не кожен використовує C" ....
sspence65

Напевно, найбезпечніший і найпростіший з усіх;)
Аняна Сілва

1

Без рішення InnoDB: ви можете скористатися процедурою don't forgot to set the the delimiter for storing the procedure with ;

CREATE PROCEDURE myproc(OUT id INT, IN otherid INT, IN title VARCHAR(255))
BEGIN
LOCK TABLES `table1` WRITE;
INSERT INTO `table1` ( `title` ) VALUES ( @title ); 
SET @id = LAST_INSERT_ID();
UNLOCK TABLES;
INSERT INTO `table2` ( `parentid`, `otherid`, `userid` ) VALUES (@id, @otherid, 1); 
END

І ви можете використовувати його ...

SET @myid;
CALL myproc( @myid, 1, "my title" );
SELECT @myid;

0

Можна було б зберегти змінну last_id_in_table1 у змінну php, щоб згодом її використовувати?

За допомогою цього last_id мені потрібно вкласти деякі записи в іншу таблицю з цим last_id, тому мені потрібно:

1) Зробіть ВСТУП та отримайте last_id_in_table1

INSERT into Table1(name) values ("AAA"); 
SET @last_id_in_table1 = LAST_INSERT_ID();

2) Для будь-яких невизначених рядків в іншій таблиці, ОНОВЛЕННЯ цих рядків з last_id_insert, створеним у вставці.

$element = array(some ids)    
foreach ($element as $e){ 
         UPDATE Table2 SET column1 = @last_id_in_table1 WHERE id = $e 
    }


-1

Для останнього та другого останнього:

INSERT INTO `t_parent_user`(`u_id`, `p_id`) VALUES ((SELECT MAX(u_id-1) FROM user) ,(SELECT MAX(u_id) FROM user  ) );

Це рішення не є безпечним за межами транзакції (тобто увімкнено автокомісію) та всередині транзакції з рівнем ізоляції транзакцій, нижчим за серійний. Дивіться: en.wikipedia.org/wiki/Isolation_(database_systems)
снорбі

-2

Просто для додавання до публікації Rodrigo, замість LAST_INSERT_ID () у запиті ви можете використовувати SELECT MAX (id) З таблиці1 ;, але ви повинні використовувати (),

INSERT INTO table1 (title,userid) VALUES ('test', 1)
INSERT INTO table2 (parentid,otherid,userid) VALUES ( (SELECT MAX(id) FROM table1), 4, 1)

Це рішення не є безпечним за межами транзакції (тобто увімкнено автокомісію) та всередині транзакції з рівнем ізоляції транзакцій, нижчим за серійний. Дивіться: en.wikipedia.org/wiki/Isolation_(database_systems)
снорбі

-9

Якщо вам потрібно мати mysql, після вашого запиту, останній автоматичний додатковий ідентифікатор без іншого запиту, введіть свій код:

mysql_insert_id();

15
Не рекомендую mysql_ * - ці застарілі
німецька Румма

Клетус отримав 106 upvotes і відзначений відповідь на mysql_insert_id тут: stackoverflow.com/a/897361/153923
jp2code

2
клеттус відповідав на це у 2009 році! mysql застаріло, краще використовувати mysqli і mysqli_insert_id ie2.php.net/mysqli_insert_id
Мацей Папроцький

2
Лука. Якщо ви видалите цю застарілу відповідь, я вірю, що ваші репутаційні бали повернуться.
TecBrat

Ще одна допустима альтернатива застарілому пропозиції - PDO :: lastInsertId ( php.net/manual/en/pdo.lastinsertid.php )
w5m
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.