Jak uzyskać ostatnio wstawiony identyfikator tabeli MySQL w PHP?

93

Mam tabelę, do której często wstawiane są nowe dane. Muszę zdobyć ostatni identyfikator stołu. Jak mogę to zrobić?

Czy jest podobny do SELECT MAX(id) FROM table?

gweg
źródło
1
tak, to zapytanie zwróci ostatni identyfikator tabeli. Ale jeden warunek jest taki, że identyfikator musi być kluczem podstawowym. Możesz więc uniknąć pokuty.
satish
7
@sathish: Głównym problemem tej metody jest współbieżność .
Christian C. Salvadó
3
Aby rozwinąć: Problem polega na tym, że jeśli ktoś inny wstawi coś do tabeli między twoim INSERTa zapytaniem MAX(id), możesz otrzymać identyfikator, który nie jest twoim ostatnim identyfikatorem.
deceze
3
@Jocelyn to pytanie zostało zadane rok później z tysiącami mniej wyświetleń niż to pytanie.
Naftali aka Neal
3
@Neal, masz rację. Drugie pytanie należy zamknąć jako duplikat tego.
Jocelyn

Odpowiedzi:

134

Jeśli używasz PDO, użyj PDO::lastInsertId.

Jeśli używasz Mysqli, użyj mysqli::$insert_id.

Jeśli nadal używasz MySQL:

Proszę nie używać mysql_*funkcji w nowym kodzie . Nie są już obsługiwane i są oficjalnie przestarzałe . Widzisz czerwone pudełko ? Zamiast tegodowiedz się o przygotowanych wyciągach i korzystaj z PDO lub MySQLi - ten artykuł pomoże Ci zdecydować, które. Jeśli wybierzesz PDO, oto dobry tutorial .

Ale jeśli musisz, użyj mysql_insert_id.

zamrozić
źródło
Problem z tym polega na tym, że jeśli dzieje się dużo wstawek (np. Twoja baza danych również coś rejestruje), możesz uzyskać zły identyfikator.
Mike
@Mike Nie, jeśli używać mysql_insert_id zaraz po TWOJEJ mysql_query. Jeśli oczywiście wykonasz kilka innych zapytań na tym samym połączeniu pomiędzy, cóż, nic nie może ci w tym pomóc.
deceze
7
Aby zagwarantować, że NIGDY nie otrzymasz błędnego identyfikatora, owiń swój kod transakcją .
Marcelo Assis
28
mysql upewnia się, że jest to ostatni identyfikator BIEŻĄCEGO POŁĄCZENIA, więc nie będzie żadnych problemów, jeśli umieścisz tę instrukcję bezpośrednio po zapytaniu wstawiającym. Nie martw się, że inne procesy wykonują wstawianie. Nie ma potrzeby pakowania tego w transakcję. Podręcznik mysql mówi: „Wygenerowany identyfikator jest przechowywany na serwerze dla każdego połączenia. Oznacza to, że wartość zwracana przez funkcję danemu klientowi jest pierwszą wartością AUTO_INCREMENT wygenerowaną dla ostatniej instrukcji wpływającej na kolumnę AUTO_INCREMENT przez tego klienta . To jest powód, dla którego nie powinieneś używać funkcji select MAX (ID)
woens
1
@ deceze, o co chodzi z tym PDOuprzedzeniem, które widzimy wszędzie? Spójrzmy ponownie na porównanie funkcji . Oczywiste jest, że mysqlijest zwycięzcą, gdy musisz ubrudzić sobie ręce rzeczami niskiego poziomu. Innymi słowy, nawet jeśli ktoś wybierze ChNP, w końcu i tak będzie musiał użyć mysqli.
Pacerier
52

jest funkcja, która wie, jaki był ostatni identyfikator wstawiony w bieżącym połączeniu

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

plus używanie max jest złym pomysłem, ponieważ może to prowadzić do problemów, jeśli twój kod jest używany w tym samym czasie w dwóch różnych sesjach.

Ta funkcja nazywa się mysql_insert_id

RageZ
źródło
2
mysql _ (...) jest przestarzałe w wersji PHP> = 5.5.
Iago
Tak, po prostu to pamiętam. :)
Iago
22

W porządku. Możesz również użyć LAST_INSERT_ID ()

x2.
źródło
1
Dlaczego mówisz, że select max(id)from tablejest OK?
Pacerier
19

Z ChNP :

$pdo->lastInsertId();

Z Mysqli :

$mysqli->insert_id;

Proszę nie używać mysql_*funkcji w nowym kodzie . Nie są już obsługiwane i są oficjalnie przestarzałe . Widzisz czerwone pudełko ? Zamiast tegodowiedz się o przygotowanych wyciągach i korzystaj z PDO lub MySQLi - ten artykuł pomoże Ci zdecydować, które. Jeśli wybierzesz PDO, oto dobry tutorial .

Naftali alias Neal
źródło
8

To, co napisałeś, dałoby ci najwięcej, idzakładając, że są unikalne i automatycznie zwiększane, co byłoby w porządku, zakładając, że nie przeszkadza ci zapraszanie problemów ze współbieżnością.
Ponieważ używasz MySQL jako bazy danych, istnieje określona funkcja, LAST_INSERT_ID()która działa tylko na bieżącym połączeniu, które wykonało wstawienie.
PHP oferuje specjalną funkcję do tego zwaną mysql_insert_id.

dlamblin
źródło
6

Spróbuj, to powinno działać dobrze:

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

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

echo mysqli_insert_id($link);
Sandhu
źródło
1
Dziękuję, że zauważyłeś. Edytowałem kod, właściwie jest to $ link (zmienna utrzymująca połączenie)
Sandhu Kwietnia
3

Aby uzyskać ostatnio wstawiony identyfikator w codeigniter Po wykonaniu zapytania wstawiania wystarczy użyć jednej funkcji wywołanej insert_id()w bazie danych, zwróci ona ostatnio wstawiony identyfikator

Dawny:

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

w jednej linii

echo $this->db->insert('mytable',$data)->insert_id();
Narsimha
źródło
2

Możesz uzyskać ostatni wstawiony identyfikator za pomocą wbudowanej funkcji php mysql_insert_id();

$id = mysql_insert_id();

możesz również uzyskać najnowszy identyfikator

$id = last_insert_id();
Rahul
źródło
5
Jest to również błędne, ponieważ sugeruje użycie przestarzałej biblioteki. Naprawdę, usuń to
STT LCU,
@STTLCU Który fragment kodu jest przestarzały?
TheBlackBenzKid
@TheBlackBenzKid oba, ponieważ są oparte na funkcjach mysql_ *
STT LCU
@Rahul $ id = last_insert_id (); nie działa, ponieważ może być przestarzały.
Esha
2

Można go używać mysql_insert_id(), ale jest jedna szczególna uwaga na temat jego używania, należy go wywołać po wykonaniu zapytania INSERT, czyli w tej samej sesji skryptu. Jeśli go użyjesz w inny sposób, nie będzie działać poprawnie.

Mihail Dimitrov
źródło
2

Czyste i proste -

$selectquery="SELECT id FROM tableName ORDER BY id DESC LIMIT 1";
$result = $mysqli->query($selectquery);
$row = $result->fetch_assoc();
echo $row['id'];
Hitesh
źródło
1

UWAGA: jeśli wykonasz wiele operacji wstawiania za pomocą jednej instrukcji, mysqli :: insert_id nie będzie poprawne.

Stół:

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

Teraz, jeśli to zrobisz:

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

MySqli :: insert_id będzie mieć wartość 1, a nie 3.

Aby uzyskać poprawną wartość, wykonaj:

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

To był dokument, ale jest trochę niejasny.

bartonlp
źródło
1

Wolę używać czystej składni MySQL, aby uzyskać ostatni identyfikator auto_increment tabeli, którą chcę.

php mysql_insert_id () i mysql last_insert_id () podają tylko identyfikator ostatniej transakcji.

Jeśli chcesz, aby ostatni identyfikator auto_incremented dowolnej tabeli w Twoim schemacie (nie tylko ostatniej transakcji), możesz użyć tego zapytania

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

Otóż ​​to.

syjust
źródło
mam co do tego wątpliwości, ponieważ ten kod SQL jest po prostu błędny w kontekście pytania ... Również ta metoda jest podatna na możliwe warunki wyścigu, gdy dwóch lub więcej klientów wykonuje ten kod SQL w tym samym czasie ... nie jestem pewien jak szybko te dane kolumny są aktualizowane po wstawieniu, co budzi wątpliwości ... Funkcje PHP, które mogą uzyskać ostatni identyfikator, są oparte na poziomie połączenia / sesji (robi mniej więcej to samo, co LAST_INSERT_ID () MySQL ), co powoduje, że stan wyścigu jest zapisywany
Raymond Nijland
1

Szkoda, że ​​nie widzę odpowiedzi na przykładzie.

Korzystanie z 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

Korzystanie z PDO :: lastInsertId :

$sql="INSERT INTO table (col1, col2, col3) VALUES (val1, val2, val3)";
$database->query($sql);
$last_inserted_id=$database->lastInsertId(); // returns last ID
Rdza
źródło
0

Używając MySQLitransakcji, czasami nie byłem w stanie uzyskać mysqli::$insert_id, ponieważ zwracała 0. Szczególnie jeśli korzystałem z procedur składowanych, które wykonują INSERTs. Jest więc inny sposób w ramach transakcji:

<?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;
}

?>
Ciężkie bombardowanie
źródło
0

Użyj mysqli jako depricating 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();
?>
Biedna Rao
źródło
-1

próbowałem

mysqli_insert_id($dbConnectionObj)

Zwraca to ostatnio wstawiony identyfikator bieżącego połączenia, więc jeśli prawidłowo zarządzasz połączeniami, powinno to działać. Przynajmniej dla mnie zadziałało.

user2166373
źródło
1
To ta sama odpowiedź, co tutaj stackoverflow.com/a/41564156/5468463
Vega
Przy negatywnej liczbie głosów ten zbędny wpis może zostać usunięty przez społeczność, zamiast przeszkadzać moderatorom.
mickmackusa