2013-06-14 21 views
136

OK, powiedzmy, że robię mysql INSERT w jednym z moich tabel, a tabela ma kolumnę item_id, która jest ustawiona na autoincrement i primary key.Uzyskaj nowy identyfikator klucza podstawowego rekordu z kwerendy wstawiania mysql?

W jaki sposób można uzyskać zapytanie o wartość nowo wygenerowanego klucza podstawowego item_id w tym samym zapytaniu?

Obecnie używam drugą kwerendę, aby pobrać identyfikator, ale to nie wydaje się jak dobrej praktyki rozważa to może produkować zły wynik ...

Jeśli nie jest to możliwe, to jaka jest najlepsza praktyka, aby zapewnić Odzyskuję poprawny identyfikator?

+1

Nie ma sposobu, aby zwrócić coś z takiego zapytania "WSTAW"; dlaczego uważasz, że może to spowodować zły wynik? –

+3

Cóż, jeśli proces jest wykonywany osobno przez 2 osoby, to może się zdarzyć, że lista procesów zachodzi na siebie, ponieważ musisz wykonać dwa osobne zapytania? –

+0

Możliwy duplikat wiersza [PHP/MySQL insert then get 'id'] (http://stackoverflow.com/questions/897356/php-mysql-insert-row-then-get-id) –

Odpowiedz

183

Musisz użyć LAST_INSERT_ID() funkcję: http://dev.mysql.com/doc/refman/5.0/en/information-functions.html#function_last-insert-id

np

INSERT INTO table_name (col1, col2,...) VALUES ('val1', 'val2'...); 
SELECT LAST_INSERT_ID(); 

To będzie cię z powrotem wartość PRIMARY KEY ostatniego wiersza, który ty brzmieniu:

Wygenerowany identyfikator jest przechowywany na serwerze pod numerem dla każdego połączenia. Oznacza to, że wartość zwrócona przez funkcję do danego klienta jest pierwszą wartością AUTO_INCREMENT wygenerowaną dla najnowszej instrukcji wpływającej na kolumnę AUTO_INCREMENT tego klienta.

Na to nie mają wpływu inne zapytania, które mogą być uruchomione na serwerze od innych użytkowników.

+6

tak, ale co jeśli w międzyczasie (między zapytaniami na liście procesów) wstawiono jakiś inny wiersz? Czy jest jakiś sposób, aby napisać kwerendę wstawiania tak, aby to wyprowadzić? –

+0

OK, widzę ... ostatni identyfikator wstawki zapytania jest nagrywany, nawet jeśli nie jest zalogowany w wyniku ... $ mysqli-> insert_id –

+12

Spowoduje to przywrócenie wartości "PRIMARY KEY" z ostatniego wiersz, który * wstawiłeś *, ponieważ jest to połączenie - każde połączenie z serwerem zachowa dla niego własną wartość. Zaktualizowałem odpowiedź, aby to wyjaśnić. –

12

Z dokumentacji LAST_INSERT_ID():

identyfikator, który został wygenerowany jest utrzymywana na serwerze na podstawie per związku

to jeśli masz dwa oddzielne wnioski do skryptu jednocześnie nie wpłyną one na siebie nawzajem ", chyba że używasz trwałego połączenia).

13

Oto czego szukasz !!!

select LAST_INSERT_ID() 

To najlepsza alternatywa SCOPE_IDENTITY() funkcji używanych w SQL Server.

Należy również pamiętać, że działa to tylko pod warunkiem, że Last_INSERT_ID() jest uruchamiany po zapytaniu Insert. To jest zapytanie, które zwraca identyfikator wstawiony w schemacie. Nie możesz uzyskać identyfikatora ostatniej wstawionej tabeli.

Aby uzyskać więcej informacji prosimy przejść przez odnośnik The equivalent of SQLServer function SCOPE_IDENTITY() in mySQL?

13

strzeżcie się !! "LAST_INSERT_ID()", jeśli próbujesz zwrócić wartość klucza podstawowego w PHP.

Wiem, że ten wątek nie jest oznaczony jako php, ale dla każdego, kto natknął się na tę odpowiedź, który chciałby zwrócić identyfikator wstawki do MySQL z wstawionej w skrypcie PHP przy użyciu standardowych wywołań mysql_query - nie zadziała i nie będzie oczywisty bez przechwytywania błędów SQL.

Nowsza wersja mysqli obsługuje wiele zapytań - w rzeczywistości LAST_INSERT_ID() to drugie zapytanie z oryginału.

IMO oddzielne SELECT do identyfikacji ostatniego klucza podstawowego jest bezpieczniejsze niż opcjonalna funkcja mysql_insert_id() zwracająca identyfikator AUTO_INCREMENT wygenerowany z poprzedniej operacji INSERT.

+4

'LAST_INSERT_ID' to funkcja MySQL na połączenie. Jeśli wyszukujesz ostatni identyfikator wkładki, możliwe jest, że oddzielne połączenie wykona zapis i otrzymasz zły identyfikator. –

+0

@ExplosionPills 'mysql_insert_id()' działa również na podstawie połączenia, ale też cierpi na dziwne zachowanie, jak widać tutaj http://stackoverflow.com/a/897374/1305910 w komentarzu Cliffordlife - nevermind powinniśmy wszyscy mieć używałem 'mysqli' – RozzA

-6

Jeśli LAST_INSERT_ID() działa trochę dziwne lub nie działa tak, jak jest dla mnie wtedy użyć tego prostego komunikatu ...

--- INSERT STATEMENT GOES HERE --- SELECT id FROM table ORDER BY id DESC LIMIT 1;

ten powinien zwrócić największą ID w tabeli, a więc ostatni ID włożona

+2

Myślę, że jeśli masz wiele wątków wstawiających do tabeli, możesz czasami otrzymać ten sam identyfikator, co ktoś inny, jeśli nie możesz wystarczająco szybko zakończyć INSERT i SELECT, a twój poziom izolacji jest zbyt niski. –

+0

to cierpi na "stan wyścigu" – RozzA

3

Jeśli potrzebujesz wartość przed wstawić wiersz:

CREATE FUNCTION `getAutoincrementalNextVal`(`TableName` VARCHAR(50)) 
    RETURNS BIGINT 
    LANGUAGE SQL 
    NOT DETERMINISTIC 
    CONTAINS SQL 
    SQL SECURITY DEFINER 
    COMMENT '' 
BEGIN 

    DECLARE Value BIGINT; 

    SELECT 
     AUTO_INCREMENT INTO Value 
    FROM 
     information_schema.tables 
    WHERE 
     table_name = TableName AND 
     table_schema = DATABASE(); 

    RETURN Value; 

END 

można to wykorzystać w wkładki:

INSERT INTO 
    document (Code, Title, Body) 
VALUES (    
    sha1(concat (convert (now() , char), ' ', getAutoincrementalNextval ('document'))), 
    'Title', 
    'Body' 
); 
+0

Ten nie wydaje się być dobrym pomysłem? Jeśli dwaj klienci wywołają tę funkcję w tym samym czasie, będą myśleć, że wstawiają ten sam identyfikator, gdy w rzeczywistości nie są. Jeden będzie nieco wolniejszy we wkładce i otrzyma następny identyfikator bez wiedzy. – CarCar

+0

Użyjesz tego kodu wewnątrz transakcji. –

Powiązane problemy