2008-11-14 17 views
6

Zawsze słyszę, że używanie "lastInsertId" (lub mysql_insert_id(), jeśli nie używasz PDO) jest złe. W przypadku wyzwalaczy jest to oczywiście, ponieważ może zwrócić coś, co nie jest ostatnim identyfikatorem utworzonym przez twój INSERT.Alternatywa dla "PDO :: lastInsertId"/"mysql_insert_id"

$DB->exec("INSERT INTO example (column1) VALUES ('test')"); 
// Usually returns your newly created ID. 
// However when a TRIGGER inserts into another table with auto-increment: 
// -> Returns newly created ID of trigger's INSERT 
$id = $DB->lastInsertId(); 

Co to jest alternatywa?

Odpowiedz

2

Jeśli wybierzesz trasę ADOdb (http://adodb.sourceforge.net/), możesz utworzyć identyfikator wkładki przed ręką i jawnie określić identyfikator podczas wstawiania. To może być implementowane przenośnie (ADOdb obsługuje wiele różnych baz danych ...) i gwarantuje, że używasz poprawnego identyfikatora insertów.

Typ danych PostgreSQL SERIAL jest podobny, z wyjątkiem tego, że jest to tabela/sekwencja, należy określić tabelę/sekwencję, dla której ma zostać wstawiony ostatni identyfikator wstawki, gdy użytkownik tego zażąda.

+0

+1 .Pisałem moja odpowiedź, kiedy pisałeś, –

+0

Wygląda całkiem interesująco. Jaki wpływ ma ta technika na wydajność? – BlaM

+2

Tak, ale co zrobisz, jeśli utkniesz w ChNP? – Elijah

0

To nie jest wyrafinowane i nie jest wydajne, ale jeśli wstawione dane zawierają unikalne pola, SELECT może oczywiście przynieść to, czego szukasz.

Na przykład:

INSERT INTO example (column1) VALUES ('test'); 
SELECT id FROM example WHERE column1 = 'test'; 
+0

Oczywiście;) - Ale także oczywiście dość brzydki;) – BlaM

1

myślę, to naprawdę nie jest stan wiedzy albo ale używam zapisu blokady, aby upewnić się, że naprawdę się ostatni zapisany identyfikator.

+0

Oczywiście działa również - ale blokowanie IMHO jest jeszcze większym złem w aplikacjach sieciowych o wysokiej wydajności ... – BlaM

4

IMHO jest uważane za "złe", ponieważ prawie żadna inna baza danych SQL (jeśli taka istnieje) nie ma go.

Osobiście uważam, że jest to niezwykle przydatne i chciałbym, aby nie musiałem uciekać się do innych, bardziej skomplikowanych metod na innych systemach.

+0

Przynajmniej MSSQL ma tę samą funkcję. W mojej starej pracy używanie "wstawiania identyfikatora" spowodowało poważne bóle głowy, gdy ktoś dodał wyzwalacz do stołu, który zepsuł całą witrynę - bez oczywistego powodu dla tych, którzy nie wiedzieli o tym wyzwalaczu ... – BlaM

3

Jedną z alternatyw jest użycie sekwencji zamiast niej, więc przed wykonaniem wstawki generowany jest identyfikator.

Niestety nie są one obsługiwane w MySQL, ale biblioteki takie jak Adodb mogą emulować je za pomocą innej tabeli. Myślę jednak, że sama emulacja użyje lastInsertId() lub odpowiednik ... ale przynajmniej są mniej prawdopodobne, aby mieć spust na stole, który jest czysto używane do sekwencji

-3

Można spróbować to:

$sql = "SELECT id FROM files ORDER BY id DESC LIMIT 1"; 
$PS = $DB -> prepare($sql); 
$PS -> execute(); 
$result = $PS -> fetch(); 
+3

To nie jest alternatywa w środowiskach o wysokim natężeniu ruchu. Ciągle otrzymasz błędne identyfikatory. – BlaM