Як отримати останній вставлений ідентифікатор таблиці MySQL у PHP?


93

У мене є таблиця, до якої часто вставляються нові дані. Мені потрібно отримати останній ідентифікатор таблиці. Як я можу це зробити?

Це схоже на SELECT MAX(id) FROM table?


1
так, ви за цим запитом повернете останній ідентифікатор таблиці. Але одна умова - ідентифікатор повинен бути Первинним ключем. Так ви зможете уникнути покаяння.
sathish

7
@sathish: Основна проблема цього методу - паралельність .
Крістіан С. Сальвадо,

3
Пояснити: Проблема з ним полягає в тому, що якщо хтось інший вставить щось у таблицю між вашим INSERTта запитом для MAX(id), ви можете отримати ідентифікатор, який не є вашим останнім ідентифікатором.
обдурити

3
@ Jocelyn це питання було поставлено через рік із тисячами переглядів менше, ніж це питання.
Нафталі, він же Ніл,

3
@ Ніл, ти маєш рацію. Інше питання слід закрити як копію цього.
Джоселін

Відповіді:


133

Якщо ви використовуєте PDO, використовуйте PDO::lastInsertId.

Якщо ви використовуєте Mysqli, використовуйте mysqli::$insert_id.

Якщо ви все ще використовуєте Mysql:

Будь ласка, не використовуйте mysql_*функції в новому коді . Вони більше не підтримуються і офіційно застаріли . Бачите червоне поле ? Дізнайтесянатомістьпро підготовлені твердження та використовуйте PDO або MySQLi - ця стаття допоможе вам вирішити, які. Якщо ви вибрали PDO, ось хороший підручник .

Але якщо доведеться, використовуйте mysql_insert_id.


Проблема з цим полягає в тому, що якщо у вас трапляється багато вставок (наприклад, ваша база даних також щось реєструє), ви можете отримати неправильний ідентифікатор.
Майк,

@Mike Ні, якщо ви використовуєте mysql_insert_id відразу після вашого mysql_query. Якщо, звичайно, ви виконуєте кілька інших запитів за тим самим підключенням між ними, ну, там нічого не може вам допомогти.
обдурити

7
Щоб гарантувати, що ви НІКОЛИ не отримаєте неправильний ідентифікатор, оберніть свій код транзакцією .
Марсело Ассіс

28
mysql переконується, що це останній ідентифікатор ПОТОЧНОГО ПІДКЛЮЧЕННЯ, тому не буде проблем, якщо ви введете цей оператор відразу після запиту на вставку. Не турбуйтеся про те, що інші процеси виконують вставки. Не потрібно обертати це транзакцією. У посібнику mysql сказано: "Ідентифікатор, який було створено, зберігається на сервері для кожного підключення. Це означає, що значення, повернене функцією даному клієнту, є першим значенням AUTO_INCREMENT, створеним для останнього оператора, що впливає на стовпець AUTO_INCREMENT від цього клієнта . Саме по цій причині ви повинні НЕ використовувати SELECT MAX (ID)
woens

1
@deceze, що з цією PDOупередженістю, яку ми бачимо скрізь? Давайте знову подивимося на порівняння функцій . Зрозуміло, що mysqliце переможець, коли вам потрібно забруднити руки нечистими речами. Іншими словами, навіть якщо хтось обирає ЗНП, він зрештою все mysqliодно потребуватиме використання .
Pacerier

53

є функція, яка знає, який останній ідентифікатор був вставлений у поточне з'єднання

mysql_query('INSERT INTO FOO(a) VALUES(\'b\')');
$id = mysql_insert_id();

плюс використання max - це погана ідея, оскільки це може призвести до проблем, якщо ваш код використовується одночасно в двох різних сесіях.

Ця функція називається mysql_insert_id


2
mysql _ (...) не підтримується у версії PHP> = 5.5.
Яго

Так, я просто це пам'ятаю. :)
Яго

22

Нічого страшного. Також ви можете використовувати LAST_INSERT_ID ()


1
Чому ти кажеш, що select max(id)from tableце нормально?
Pacerier

18

З PDO :

$pdo->lastInsertId();

З Mysqli :

$mysqli->insert_id;

Будь ласка, не використовуйте mysql_*функції в новому коді . Вони більше не підтримуються і офіційно застаріли . Бачите червоне поле ? Дізнайтесянатомістьпро підготовлені твердження та використовуйте PDO або MySQLi - ця стаття допоможе вам вирішити, які. Якщо ви вибрали PDO, ось хороший підручник .



8

Те, що ви написали, принесло б вам найбільше idприпущення, що вони були унікальними та автоматично збільшувались, що було б непогано, якщо ви гаразд запрошуєте проблеми з паралельністю.
Оскільки ви використовуєте MySQL як базу даних, існує конкретна функція, LAST_INSERT_ID()яка працює лише на поточному з'єднанні, яке здійснило вставку.
PHP пропонує спеціальну функцію для того, що називається mysql_insert_id.


6

Спробуйте, це має працювати нормально:

$link = mysqli_connect("localhost", "my_user", "my_password", "world");

$query = "INSERT blah blah blah...";
$result = mysqli_query($link, $query);

echo mysqli_insert_id($link);

1
Дякую, що помітили. Я відредагував код, насправді це $ link (змінна, що утримує з'єднання)
Sandhu,

3

Ви можете отримати останній вставлений ідентифікатор за допомогою вбудованої функції php mysql_insert_id();

$id = mysql_insert_id();

Ви також отримаєте останній ідентифікатор

$id = last_insert_id();

4
Крім того, це неправильно, оскільки пропонується використовувати застарілу бібліотеку. Дійсно, видаліть це
STT LCU

@STTLCU Який тут фрагмент застарілий?
TheBlackBenzKid

@TheBlackBenzKid обидва, оскільки вони засновані на функціях mysql_ *
STT LCU

@Rahul $ id = last_insert_id (); не працює, оскільки може бути застарілою.
Еша,

3

Отримання останнього вставленого ідентифікатора в codeigniter Після виконання запиту на вставку просто використовуйте одну функцію, що викликається insert_id()в базі даних, вона поверне останній вставлений ідентифікатор

Приклад:

$this->db->insert('mytable',$data);
echo $this->db->insert_id(); //returns last inserted id

в один рядок

echo $this->db->insert('mytable',$data)->insert_id();

3

Це нормально використовувати mysql_insert_id(), але є одна конкретна примітка щодо його використання, ви повинні викликати його після виконаного запиту INSERT, означає в тому ж сеансі сценарію. Якщо ви використовуєте його в іншому випадку, це буде працювати неправильно.


2

Чисто і просто -

$selectquery="SELECT id FROM tableName ORDER BY id DESC LIMIT 1";
$result = $mysqli->query($selectquery);
$row = $result->fetch_assoc();
echo $row['id'];

1

ПРИМІТКА: якщо ви зробите кілька встав з одним оператором mysqli :: insert_id, буде неправильним.

Стіл:

create table xyz (id int(11) auto_increment, name varchar(255), primary key(id));

Тепер, якщо ви це зробите:

insert into xyz (name) values('one'),('two'),('three');

Mysqli :: insert_id буде 1, а не 3.

Щоб отримати правильне значення:

mysqli::insert_id + mysqli::affected_rows) - 1

Це був документ, але трохи неясний.


1

Я вважаю за краще використовувати чистий синтаксис MySQL, щоб отримати останній ідентифікатор auto_increment таблиці, яку я хочу.

php mysql_insert_id () та mysql last_insert_id () дають лише ідентифікатор останньої транзакції.

Якщо вам потрібен останній автоматично_інкрементований ідентифікатор будь-якої таблиці у вашій схемі (не тільки останньої транзакції), ви можете використовувати цей запит

SELECT AUTO_INCREMENT FROM information_schema.TABLES
    WHERE TABLE_SCHEMA = 'my_database' 
    AND TABLE_NAME = 'my_table_name';

Це воно.


я сумніваюся в цьому, оскільки цей SQL просто помилковий у контексті питання .... Також цей метод відчуває схильність до можливих перегонових умов, коли два або більше клієнтів виконують цей SQL приблизно одночасно ... я не впевнений як швидко оновлюються дані цих стовпців після вставки, що викликає у мене сумнів. Функції PHP, які можуть отримати останній ідентифікатор, засновані на рівні підключення / сеансу (робить більш-менш те саме, що і LAST_INSERT_ID () MySQL ), що робить збереження стану гонки
Реймонд

1

Сумно не бачити відповідей на прикладі.

Використання Mysqli :: $ insert_id :

$sql="INSERT INTO table (col1, col2, col3) VALUES (val1, val2, val3)";
$mysqli->query($sql);
$last_inserted_id=$mysqli->insert_id; // returns last ID

Використання PDO :: lastInsertId :

$sql="INSERT INTO table (col1, col2, col3) VALUES (val1, val2, val3)";
$database->query($sql);
$last_inserted_id=$database->lastInsertId(); // returns last ID

0

Використовуючи MySQLiтранзакцію, я іноді не міг отримати mysqli::$insert_id, оскільки вона повертала 0. Особливо, якщо я використовував збережені процедури, які виконували INSERTs. Отже, є ще один спосіб у транзакції:

<?php

function getInsertId(mysqli &$instance, $enforceQuery = false){
    if(!$enforceQuery)return $instance->insert_id;

    $result = $instance->query('SELECT LAST_INSERT_ID();');

    if($instance->errno)return false;

    list($buffer) = $result->fetch_row();

    $result->free();

    unset($result);

    return $buffer;
}

?>

0

Використовуйте mysqli, оскільки mysql зображує

<?php
$mysqli = new mysqli("localhost", "yourUsername", "yourPassword", "yourDB");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}
// Conside employee table with id,name,designation
$query = "INSERT INTO myCity VALUES (NULL, 'Ram', 'Developer')";
$mysqli->query($query);

printf ("New Record has id %d.\n", $mysqli->insert_id);

/* close connection */
$mysqli->close();
?>

0

я намагався

mysqli_insert_id ($ dbConnectionObj)

Це повертає останній вставлений ідентифікатор поточного з'єднання, тому, якщо ви належним чином керуєте своїми з'єднаннями, це повинно працювати. Працював у мене принаймні.


0

Будь ласка, використовуйте PDP, а потім спробуйте це

$stmt = $db->prepare("...");
$stmt->execute();
$id = $db->lastInsertId();


-1

Під час усього цього обговорення я припускаю, що причина перевірки максимального ідентифікатора полягає в тому, щоб знати, який ідентифікатор повинен бути наступним .. (якщо мій максимальний ідентифікатор - 5, то наступним буде 5 + 1 = 6).

>> Якщо це не причина, найкращі вибачення

Випадок, якщо хтось інший ВСТАВЛЯЄ інформацію між вашим ПЕРЕВІРКОМ та ВСТАВКОЮ, це дасть вам неправильний ідентифікатор.

Тож це можна вирішити, якщо ви створили хеш, який міг би містити позначку часу або інше унікальне значення.

Тоді в тій самій функції ви можете вставити свою інформацію з порожніми значеннями та ваш хеш. Це створило б ідентифікатор, якщо ви вибрали AUTO_INCRECEMENT.

Тоді в тій самій функції у вас все одно буде ваш хеш, і ви можете шукати ідентифікатор з тим самим хешем. А потім ви можете заповнити порожні значення за допомогою mysql UPDATE.

Це включає в себе трохи більше з'єднань, але це все одно спосіб зробити це ...

Удачі у її вирішенні.


-2

Якщо у вашій таблиці є стовпець AUTO INCREMENT, такий як UserID, Emp_ID, .., тоді ви можете використовувати цей запит, щоб отримати останній вставлений запис SELECT * FROM ім'я_таблиці, де UserID = (виберіть MAX (UserID) з table_name) У коді PHP:

$con = mysqli_connect('localhost', 'userid', 'password', 'database_name');
                                if (!$con) {
                                    die('Could not connect: ' . mysqli_error($con));
                                }
                                $sql = "SELECT * FROM table_name where UserID=(select MAX(UserID)from table_name)";
                                $result = mysqli_query($con, $sql);

Тоді ви можете використовувати отримані дані як свою вимогу


Не шифруйте паролі , коли зловмисник отримає БД, він також отримає ключ шифрування.
zaph

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.