Last_Insert_id()

Moin ich hab habe ein Problem mit der Mysql funktion Last_insert_id()
Wenn man nämlichen Kommentare zu einer Aktion hinzufügen möchte fügt sich einmal der Kommentar in die Tabelle Kommentareein (mit Auto_increment) und dann soll ein ein weiterer Eintrag in die Tabelle Aktionen_Kommentaremit der ID des zuvor eingetragenen Kommentars und der ID des Autors.
Ich hab gelesen Last_insert_id() soll da helfen und hab also folgenden Script:

mysql_query("INSERT INTO Kommentare (Autor,Kommentar) VALUES ('".$_SESSION['ID']."','".$_POST['Kommentar']."'); " ."INSERT INTO Aktionen_Kommentare (Aktion,Kommentar) VALUES " ."('".$_GET['id']."',LAST_INSERT_ID() );")Das klappt aber leider nicht… findet jemand den Fehler?
Danke!

Evtl zur Ergänzung der Fehler:
You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‚INSERT INTO Aktionen_Kommentare (Aktion,Kommentar) VALUES (‚11‘,LAST_INSER‘ at line 1

Zwei Inserts in einem Query sind doch okay oder?

Ich denke, zwei Queries in einem „Query“ gehen auf die Art generell nicht. Probier mal, die beiden Queries getrennt abzusetzen (also mit zwei mysql_query-Aufrufen).

das müsste eigendlich funktionieren, aber da habe ich eine generelle Frage zu php. Angenommen zwei Verschiedene Personen öffnen gleichzeitig eine Seite von einem Server, geht php dann beide nacheinander oder gleichzeitig durch? Da hatte ich so meine bedenken

Die SQL-Funktion LAST_INSERT_ID und die PHP-Funktion mysql_insert_id sind beide sicher vor Race Conditions, ja. Das MySQL-Handbuch sagt dazu:

The ID that was generated is maintained in the server on a per-connection basis. This means that the value returned by the function to a given client is the first AUTO_INCREMENT value generated for most recent statement affecting an AUTO_INCREMENT column by that client.

Alles mit LIMIT und ORDER BY oder MAX(id) oder was man dazu im Internet so findet, um die letzte eingefügte ID zu ermitteln, ist unsicher. (Ich habe das mal getestet.)

Es wäre also hier kein Problem, mit zwei mysql_query-Befehlen zwei verschiedene SQL-Queries abzuschicken.

Es gibt DB-Funktionen, die mehrere Queries in einem String zulassen (PHP: mysqli::multi_query - Manual), aber ich habe da so meine Bedenken, ob das (a) eine gute Idee ist und (b) ein Race Condition-Problem auflösen würde.

Bei ähnlich gelagerten Problemstellungen, bei denen LAST_INSERT_ID keine Alternative ist, würde ich zu Transaktionen raten (werden vom „alten“ mysql-Adapter nicht unterstützt, aber es spricht ohnehin nichts dagegen, mysqli oder pdo einzusetzen – siehe PHP-Handbuch).

Edit:

Oh, pardon, ich habe gedacht, die Frage bezieht sich bestimmt auf SQL-Statements. :slight_smile: PHP-Skripte werden (normalerweise) gleichzeitig ausgeführt. Das heißt, der Server könnte erst einen Befehl vom Request von Besucher A ausführen, dann einen von Besucher B, dann erst den nächsten von Besucher A.

:smiley: na danke erstmal! Da hatte ich halt das Problem, dass ich mir da sone Chaos-Theorie entwickelte hatte:
Besucher A → Trägt kommentar ein
Besucher B → gleichzeitig dasselbe
… Script rattert sich runter
Kommentar A mit ID 23 trägt sich ein
Kommentar B mit ID 24 trägt sich ein
Kommentar A wird mit LAST_INSERT_ID verbunden
----> last insert wäre hier aber der von B also die falsche ID
und zack alles kaputt
Wär das möglich?

Im Grunde wollte ich in #4 sagen, dass genau dieses Szenario mit LAST_INSERT_ID() (SQL) bzw. mysql_insert_id (PHP) nicht auftreten kann.

Kommentar A wird mit LAST_INSERT_ID verbunden

=> Kommentar A wird mit LAST_INSERT_ID von Besucher/Client/Connection A verbunden

Die bleibt auch dann 23, wenn Kommentar B bereits in der DB steht und Besucher B bereits die 24 zurückerhalten hat.

(Im Gegensatz zu etwa SELECT MAX(id), was man stets und ständig im Internet findet. Das würde für Besucher A unter Umständen die 24 zurückgeben, wenn die Ausführung bei Besucher B schneller war.)

Edit: Quelle zu meinem MySQL-Doku-Zitat weiter oben: http://dev.mysql.com/doc/refman/5.1/en/information-functions.html#function_last-insert-id

Edit 2:

Chaostheorie

Solche Überlegungen sind extrem wichtig und werden viel zu häufig vernachlässigt, was zu Inkonsistenzen und Informationsverlust und lustigen anderen Fehlern führen kann. „Threadsicherheit“ und „Race Condition“ wären Stichwörter.

nein ist nicht möglich!

last_insert_id bezieht sich IMMER auf die Datenbankverbindung - d.h. 2 Skriptaufrufe = 2 Verbindungen = 2 unterschiedliche last_insert_id

Besucher A wird 23 erhalten, und Besucher B erhält 24 => kein Problem diese Situation

Okay super, das ist einleuchtend!
Da bin ich dann erstmal beruhigt und chaos-theoretisier dann mal immerschön weiter :wink:
Vielen Dank nochmal
Jokus