auto-increment/id aus Datenbank-Tabelle auslesen und darstellen
fratso
- php
Moin,
mit untenstehendem kleinen code versuche ich bei jedem Neueintrag in eine Tabelle die aktuelle (letzte +1) id herauszufinden.
Im Moment gibt echo immer nur 1 aus, egal wie hoch 'id' wirklich ist.
Da es vor den lezten Änderungen am code noch funktionierte, ich mir aber nicht gemerkt habe, was genau jetzt anders ist, habe ich vom vielen Kopfschütteln bereits Nackenschmerzen.
Sieht jemand den Fehler? Ist es der nicht vorhandene Bezug zum Namen der Tabelle in der mysql-db? Wie ist die korrekte Syntax?
Vielen Dank, liebe Grüße
fratso
Nun zum code:
<?php
mysql_connect("localhost","Name","Paßwort") or die ("Keine Verbindung moeglich");
mysql_select_db("Datenbankname") or die ("Die Datenbank existiert nicht");
unset($zaehler);
$zaehler = mysql_insert_id() + 1;
echo $zaehler;
?>
Hello,
Sieht jemand den Fehler? Ist es der nicht vorhandene Bezug zum Namen der Tabelle in der mysql-db? Wie ist die korrekte Syntax?
ich sehe 2 Fehler/Ungenauigkeiten:
MfG
Rouven
Hello,
- Die Annahme, dass letzte+1=aktuelle ist mag zwar nach deinen Beobachtungen zutreffen, aber darauf verlassen würde ich mich auf die Dauer nicht.
Was passiert nämlich, wenn zwischenzeitlich ein anderer Client dasselbe Script für sich genutzt hat?
Außerdem gilt die Verbindung (es gibt Ausnahmen) immer nur für die Laufzeit eines Scriptes.
Wenn man das Script also das nächste Mal aufruft, bekommt man eine neue Verbindung zur Datenbank und alle Werte, die unter dere alten Verbundung abrufbar waren, sind auf "Anfang" zurückgesetzt.
Das betrifft natürlich nicht die DATEN in der Datenbank, sonst wäre das DBMS wohl unbrauchbar.
Aber alle flüchtigen Metadaten der Verbindung sind davon betroffen.
Harzliche Grüße vom Berg
http://bergpost.annerschbarrich.de
Tom
Mahlzeit,
- Die Annahme, dass letzte+1=aktuelle ist mag zwar nach deinen Beobachtungen zutreffen, aber darauf verlassen würde ich mich auf die Dauer nicht.
Genau dieses Problem hatte ich mal bei einem früheren Arbeitgeber ... die von mysql_insert_id() zurückgegebene ID war zwar zu dem Zeitpunkt korrekt, während der Laufzeit des Skriptes wurden aber durch andere Nutzer weitere Einträge hinzugefügt, so dass hinterher ein ziemliches Durcheinander an IDs herrschte.
Geholfen hat damals die Verwendung von separaten Sequence-Tabellen, so dass man sich ERST eine gültige neue ID holt (die dann kein anderer mehr bekommt) und sie DANN verwendet. :-)
MfG,
EKKi
Hello,
Geholfen hat damals die Verwendung von separaten Sequence-Tabellen, so dass man sich ERST eine gültige neue ID holt (die dann kein anderer mehr bekommt) und sie DANN verwendet. :-)
Das führt dann aber zu sogenannten "verlorenen Schlüsseln".
In der IT-Steinzeit hat man deshalb mit "Nummernkreisen" gearbeitet.
Jede Stelle hatte ihren eigenen Wertebereich
Rechnungsausgang 09
Herr Meier 01 -> 09010001 bis 09019999
Frau Merkel 02 -> 09020001 bis 09029999
Herr Kohl 03 -> 09030001 bis 09039999 ### Nur der hat vergessen die Namen aufzuschreiben
usw.
Rechnungseingang 08
Keditoren Einzeklhandel 01 -> 08010000 bis 08019999
na und so weiter.
Das System war lange sehr verbreitet. Bei der TELEKOM ist das immer noch in Betrieb
Harzliche Grüße vom Berg
http://bergpost.annerschbarrich.de
Tom
yo,
Genau dieses Problem hatte ich mal bei einem früheren Arbeitgeber ... die von mysql_insert_id() zurückgegebene ID war zwar zu dem Zeitpunkt korrekt, während der Laufzeit des Skriptes wurden aber durch andere Nutzer weitere Einträge hinzugefügt, so dass hinterher ein ziemliches Durcheinander an IDs herrschte.
das ist kein problem, sondern so gewollt. mysql_insert_id ist von der jeweiligen session abhängig und nur so ist sie sinnvoll nutzbar. die funktion gibt mir die id meiner (meines Scriptes) letzten insert anweisung. ich will ja gar nicht wissen, welche id's andere benutzt haben, sondern nur meine ist interessant. auch der glaube, ich müsste immer den höchsten wert wissen führt nur in eine sackgasse. es spielt nämlich keine rolle, welchen wert ich nun gerade als id benutzte, er ist transparent. wichtig ist nur, dass die vergabe von pk-werten durch autoincrement oder von sequenzen session-gesichert ist. alles andere ist murks.
eine id zuzuteilen hat nichts, aber auch gar nichts damit zu tun, immer den aktuell höchsten wert nehmen zu müssen. da geistert ein gespenst durch die lande der dabenbank-landschaft.
Ilja
Hello Ilja,
Genau dieses Problem hatte ich mal bei einem früheren Arbeitgeber ... die von mysql_insert_id() zurückgegebene ID war zwar zu dem Zeitpunkt korrekt, während der Laufzeit des Skriptes wurden aber durch andere Nutzer weitere Einträge hinzugefügt, so dass hinterher ein ziemliches Durcheinander an IDs herrschte.
das ist kein problem, sondern so gewollt. mysql_insert_id ist von der jeweiligen session abhängig und nur so ist sie sinnvoll nutzbar. die funktion gibt mir die id meiner (meines Scriptes) letzten insert anweisung. ich will ja gar nicht wissen, welche id's andere benutzt haben, sondern nur meine ist interessant. auch der glaube, ich müsste immer den höchsten wert wissen führt nur in eine sackgasse. es spielt nämlich keine rolle, welchen wert ich nun gerade als id benutzte, er ist transparent. wichtig ist nur, dass die vergabe von pk-werten durch autoincrement oder von sequenzen session-gesichert ist. alles andere ist murks.
Ecki spielte hier auf den Designfehler an.
Er (das Programm) hat sich die _nächste_ ID besorgt, die er dann in Zukunft gerne benutzen wollte, indem er auf die vermeintlich letzte vergebene für die Tabelle eins draufgezählt hat.
Dabei hat er (oder seine Programmiererkollegen damals) nicht beachet, dass mysql_insert_id() nur die letzte von _ihm_ verwendete ID (also aus der Vergangenheit) zurückliefert. Das hast Du ja auch schon erwähnt.
Das Ganze beruht doch auf dem Irrglauben, dass MySQL die ID IMMER hochzählen würde. Hingegen ist es so designed, dass es lediglich irgendeine verfügbare ID aus dem Nummernvorrat zurückliefert.
Dass die nun meistens die nächstgrößere ist, möchte ich hier mal als Zufall bezeichnen.
Es handelt sich also in Wirklichkeit nicht um einen AUTOINCREMENT-Schlüssel, sondern nur um einen UNIQUE-AUTO-Key oder auch "Auto-Primaray-Key". Ein Unique Autoincrement Key arbeitet definitionsgemäß mit _verlorenen_ Schlüsseln in ordinaler Reihenfolge. Einmal vergeben, niemehr neu verwendet.
Darüber hinaus könnte man sich auch verlorene gestreute Schlüssel vorstellen. Sie werden zwar gestreut vergeben, aber "nie" ein zweites Mal. Dazu muss aber eine interne Tabelle erhalten bleiben, die die vergebenen, aber bereits wieder gelöschten Schlüssel speichert. Das ist vom Verfahren her recht mühselig und wird darum eigentlich nur selten gemacht (Bei Autonummern mit Zusatzbedingung der Wiederfreigabe nach X Jahren).
Die laufende Nummer ist klassisch gewachsen. Chaotische Verwaltung war in der Papierwelt nicht so gerne gesehen.
Es gibt aber auch DBMS, die die konsequente Inkrementierung des AutoIncrement-Keys verbindlich zusagen. Bei diesen kann der Schlüssel dann auch zur Ermittlung der Reihenfolge benutz werden, in der die Datensätze eingetragen wurden. Das muss man bei MySQL z.B. mit einem timestamp realisieren, der aber die Gefahr birgt, dass mehrere Datensätze denselben Timestamp bekommen. Eine Sekunde ist in einer Datenbank sehr lang ...................
MySQL hat hier meiner Meinung nach noch einen Designfehler.
Harzliche Grüße vom Berg
http://bergpost.annerschbarrich.de
Tom
Tach,
vielen Dank für die klaren und fachlich qualifizierten Antworten. Leider ist meine Frage aber weiterhin unbeantwortet.
Vielleicht noch dies zum Vorhaben: Ich möchte einen Schlüssel erstellen, der sich aus der Postleitzahl des sich registrierenden Benutzers gefolgt von einem Bindestrich und der aktuellen id erstellen. Dabei ist nicht wichtig, ob die id sonst irgendeinen Sinn hat, sondern nur, daß sie per auto_increment von der db erhöht wird.
$name = $_POST["name"];
$schluessel = $_POST ["plz"]."-".$zaehler + 1;
Leider erhöht sich der ausgelesene Wert aus der id aber - wie im Original-Beitrag beschrieben - nicht.
<?php
mysql_connect("localhost","Name","Paßwort") or die ("Keine Verbindung moeglich");
mysql_select_db("Datenbankname") or die ("Die Datenbank existiert nicht");unset($zaehler);
$zaehler = mysql_insert_id() + 1;
echo $zaehler;
?>
Wer mag helfen?
Freundlicher Gruß
fratso