MySQL: Zugriff auf eingefügten Datensatz nach INSERT
srob
- php
0 Frank Jonas0 Thomas Meinike0 srob0 Frank Jonas0 srob
Moin,
mache gerade meine ersten Schritte mit PHP/MySQL und suche Ansatz für folgendes Problem:
In eine Tabelle, deren Primärschlüssel per AUTO_INCREMENT erzeugt wird, füge ich einen DS per INSERT ein. Eine Zeile weiter im PHP-Skript benötige ich den automatisch erzeugten Schlüssel - wie komme ich an den?
Es erschien mir logisch, daß das von mysql_db_query() zurückgelieferte Result Set aus dem eingefügten DS besteht. Die MySQL-Entwicklerlogik ist wohl eine andere; beim Zugriffsversuch per mysql_fetch_array() erhalte ich die Meldung:
Supplied argument is not a valid MySQL result resource in blahblah
Bei der Durchsicht der MySQL-Funktionen von PHP fiel mir nichts auf, was in die richtige Richtung wies...
Was tun?
TIA Robert
Hallo Robert,
Es erschien mir logisch, daß das von mysql_db_query() zurückgelieferte Result Set aus dem eingefügten DS besteht.
Wenn mit dem Query ein INSERT, UPDATE oder DELETE-Statement abgeschickt wurde enthält es als Result nicht den Datensatz, den Du angelegt hast, sondern nur ein Wert, der Dir angibt, wie viele Datensätze von der Aktion betroffen sind (Bei einem INSERT i.d.R. einer). Um an den Datensatz zu kommen, mußt Du nach dem INSERT ein SELECT auf die DB durchführen.
Gruß Frank
Um an den Datensatz zu kommen, mußt Du nach dem INSERT ein SELECT auf die DB durchführen.
Hallo Frank,
danke für die schnelle Antwort!
Der Ansatz mit SELECT nach INSERT erscheint mir nicht wasserdicht, da ich annehmen muß, daß bereits DS mit identischen Feldinhalten - außer dem PK natürlich - in der DB vorhanden sind oder eine Millisekunde nach meinem INSERT eingefügt werden. Wenn ich nicht etwas übersehe, müßte ich im SELECT die Feldinhalte mit den an INSERT übergebenen Werten abgleichen, ich erhielte also eine Menge aller derartigen DS zurück.
Ich werde es mit dem Lösungsvorschlag von Thomas via mysql_insert_id() veruschen...
Gruß
Robert
Um an den Datensatz zu kommen, mußt Du nach dem INSERT ein SELECT auf die DB durchführen.
Hallo Frank,
danke für die schnelle Antwort!
Der Ansatz mit SELECT nach INSERT erscheint mir nicht wasserdicht, da ich annehmen muß, daß bereits DS mit identischen Feldinhalten - außer dem PK natürlich - in der DB vorhanden sind oder eine Millisekunde nach meinem INSERT eingefügt werden. Wenn ich nicht etwas übersehe, müßte ich im SELECT die Feldinhalte mit den an INSERT übergebenen Werten abgleichen, ich erhielte also eine Menge aller derartigen DS zurück.
Ich werde es mit dem Lösungsvorschlag von Thomas via mysql_insert_id() veruschen...
Gruß
Robert
bist du dir sicher, das in einer einzigen millisekunde genau zwei identische datensätze eingefügt werden ? wenn nicht erstelle doch noch ein feld mts (millisektimestmp) in deiner db,
vor dem insert vergebe an eine variable den wert microtime().
diesen wert mit in di db->mts schreiben, und paralell die variable mit der microtime beim select verwenden (eventuell in verbindung mit anderen eingetragenen werten).... etwa so:
$millits = microtime();
@mysql_query("INSERT INTO blabla (inhalt, name, date, mts) VALUES ('$inhalt', '$name', '$datum', '$millits')");
$get = @mysql_query("SELECT * FROM blabla WHERE inhalt='$inhalt' AND name='$name' AND datum='$datum' AND mts='$millits'");
........
greets iceX
PS: die feldlänge von microtime kann ich dir so jetzt nicht sagen (musst du dir die var $millits mal anzeigen lassen und zählen)
Hallo iceX,
bist du dir sicher, das in einer einzigen millisekunde genau zwei identische datensätze eingefügt werden ? wenn nicht erstelle doch noch ein feld mts (millisektimestmp) in deiner db,
in meinem speziellen Fall ist es unerheblich, ob zwei identische DS innerhalb eines kurzen Intervalls eingefügt werde - es genügt, daß nach dem Einfügen eines DS die Möglichkeit besteht, das bereits einer oder mehrere DS mit identischen Feldinhalten vorhanden sind. Da die DS sich nur durch den PK unterscheiden, führt ein nachfolgender SELECT zu einem Problem.
Dieses Problem entsteht nicht, wenn ich die DB den PK über AUTO_INCREMENT generieren lasse und, wie von Thomas angeregt, mit mysql_insert_id() den generierten Schlüssel erhalte. Mit dieser Vorgehensweise die Frage, ob bei einem wie auch immer konstruierten Zeitstempel die Möglichkeit von Duplikaten bei nahezu gleichzeitigem INSERT besteht, obsolet.
Die Nutzung von Zeitstempeln ist eine weit verbreitete Praxis, endlos von DB-Entwicklern diskutiert. Ich habe schon vor Jahren für mich entschieden, daß Zeitstempel als PK ausscheiden, wenn die betreffende DB eine saubere Lösung zur Erzeugung von PKs bietet - wie im Fall von MySQL.
Danke für den Tipp!
THX Robert
es genügt, daß nach dem Einfügen eines DS die Möglichkeit besteht, das bereits einer oder mehrere DS mit identischen
besteht, daß bereits...
Mit dieser Vorgehensweise die Frage, ob bei einem wie auch immer
Mit dieser Vorgehensweise ist die Frage, ...
Vielleicht sollte ich mal Mittagspause machen...
P.S.: Selbst wenn die DB keinen Mechanismus zur Generierung von PKs vorhält, läßt sich u.U. über Gespeicherte Prozeduren ein Generator entwickeln, der Zeitstempeln immer noch überlegen ist.
Robert
Hallo,
In eine Tabelle, deren Primärschlüssel per AUTO_INCREMENT erzeugt wird, füge ich einen DS per INSERT ein. Eine Zeile weiter im PHP-Skript benötige ich den automatisch erzeugten Schlüssel - wie komme ich an den?
Mit PHP: mysql_insert_id($dbref)
Mit MySQL: SELECT LAST_INSERT_ID()
MfG, Thomas
Mit PHP: mysql_insert_id($dbref)
Mit MySQL: SELECT LAST_INSERT_ID()
Hallo Thomas,
das habe ich gesucht - vielen Dank!
THX Robert
Hallo, Thomas
Mit PHP: mysql_insert_id($dbref)
Mit MySQL: SELECT LAST_INSERT_ID()
Liefert diese ID die letzte ID meiner Session oder die letzte in der Db erzeugte ID? Kann bei Massenbetrieb u.U. eine andere sein. Dieses Problem kenne ich von MS SQL-Server 7.
Gruß Frank
Liefert diese ID die letzte ID meiner Session oder die letzte in der Db erzeugte ID? Kann bei Massenbetrieb u.U. eine andere sein. Dieses Problem kenne ich von MS SQL-Server 7.
Hallo Frank,
das scheint bei den beiden unterschiedlich zu sein:
mysql_insert_id() ist Verbindungsspezifisch und wird auf dem Client geführt; es liefert also die zuletzt unter dieser Verbindung erzeugte ID.
LAST_INSERT_ID() wird auf dem Server geführt und von den AUTO_INCREMENT-Aktivitäten aller Verbindungen beeinflußt.
HTH Robert