fratso: auto-increment/id aus Datenbank-Tabelle auslesen und darstellen

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;

?>

  1. 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:

    1. mysql_insert_id arbeitet auf einer Datenbankverbindung und ermittelt _pro Verbindung_ die zuletzt vergebene AutoIncrement ID. Wenn du also eine neue Verbindung aufmachst, kann da kein sinnvolles Ergebnis kommen.
    2. Die Annahme, dass letzte+1=aktuelle ist mag zwar nach deinen Beobachtungen zutreffen, aber darauf verlassen würde ich mich auf die Dauer nicht.

    MfG
    Rouven

    --
    -------------------
    "I wish it need not have happened in my time" - "So do I, and so do all who live to see such times. But that is not for them to decide. All we have to decide is what to do with the time that is given us."  --  J.R.R. Tolkien: "The Lord Of The Rings: The Fellowship Of The Ring"
    1. Hello,

      1. 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

      --
      Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
      Nur selber lernen macht schlau
      Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)

    2. Mahlzeit,

      1. 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

      --
      sh:( fo:| ch:? rl:( br:> n4:~ ie:% mo:} va:) de:] zu:) fl:{ ss:) ls:& js:|
      1. 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

        --
        Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
        Nur selber lernen macht schlau
        Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)

      2. 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

        1. 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

          --
          Fortschritt entsteht nur durch die Auseinandersetzung der Kreativen
          Nur selber lernen macht schlau
          Ein Jammer ist auch, dass die Dummen so selbstsicher und die Klugen voller Zweifel sind. Das sollte uns häufiger zweifeln lassen :-)

  2. 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