thomas: MySQL: Werte des letzten Eintrags auslesen

Hallo zusammen!

Für ein umfangreiches System programmiere ich zurzeit eine PHP-Funktion, die einen Datensatz in einer angegeben Tabelle erstellt und dann die angeforderten Angaben zurückgibt.

Beispiel (PHP-Code):
$string = dbCreate('tableSowieso', 'name=kurt,type=5', 'number');
$string['value'] => [Wert des Angeforderten Feldes (number)]

Ich habe mich im Internet schon umgesehen und bin auf die Funktion mysql_insert_id() gestossen. Ich erhalte dann den Wert des auto_icrement-Feldes zurück. Es könnte aber sein, dass ich nicht die ID des eingetragenen Datensatzes zurückhaben will, sondern irgendein anderes Feld.
Eine SELECT-Abfrage wie zum Beispiel "SELECT FROM $table WHERE ID = mysql_insert_id();" geht auch nicht, da eventuell das auto_increment-Feld nicht "ID" heisst.
Ist es irgendwie möglich, den Namen des auto_increment-Feldes einer Tabelle auszulesen? Habt ihr vielleicht andere Ideen, wie man das Problem lösen könnte?

Übrigens: Vielleicht fragt ihr euch, warum man denn nicht einfach alle auto_increment-Felder "ID" taufen kann. Die Antwort ist folgende: Es handelt sich wie gesagt um ein sehr grosses System, an dem später unzählige Programmierer hantieren werden. Die Funktion muss deshalb mit jeglichen Ausnahmefällen arbeiten können.

Vielen Dank für eure Hilfe!

LG Thomas

  1. echo $begrüßung;

    Ist es irgendwie möglich, den Namen des auto_increment-Feldes einer Tabelle auszulesen?

    Es kann in einer Tabelle nur ein auto_increment-Feld geben. mysql(i)_insert_id() liefert den Wert genau dieses Feldes. Dessen Name ist unerheblich.

    echo "$verabschiedung $name";

    1. Es kann in einer Tabelle nur ein auto_increment-Feld geben. mysql(i)_insert_id() liefert den Wert genau dieses Feldes. Dessen Name ist unerheblich.

      Hallo!

      Danke für deine Antwort. Das Problem ist, dass ich nach dem Eintragen den _gesamten_ Datensatz auslesen will, also nicht nur der Wert des auto_increment-Feldes. Ich denke das geht nur, indem man nach dem Eintragen wieder eine SELECT-Abfrage platziert. Das Problem ist: wie bekomme ich den zuletzt eingetragenen Eintrag einer Tabelle, deren Struktur völlig egal sein muss?
      Wenn man zum Beispiel wüsste, dass in der Tabelle das auto_increment-Feld "ID" existiert wäre das kein Problem (-> "SELECT FROM $table WHERE ID = mysql_insert_id();"), das auto_increment-Feld - falls überhaupt eines existiert - könnte aber auch einen anderen Namen tragen.

      Hat jemand eine Idee?

      Liebe Grüsse

      1. Hallo,

        Es kann in einer Tabelle nur ein auto_increment-Feld geben. mysql(i)_insert_id() liefert den Wert genau dieses Feldes. Dessen Name ist unerheblich.

        Das Problem ist, dass ich nach dem Eintragen den _gesamten_ Datensatz auslesen will, also nicht nur der Wert des auto_increment-Feldes.

        das heißt, Du willst die Default-Werte der Spalten auslesen, die Du nicht selbst explizit setzt? Schließlich hast Du ja alle anderen Spaltenwerte bei Deinem INSERT zur Verfügung, so dass Du diese nicht noch einmal auslesen müsstest. Hmm, es könnte sein, dass anschließend INSERT-Trigger ausgelöst werden, an deren Resultat Du interessiert bist.

        Wenn man zum Beispiel wüsste, dass in der Tabelle das auto_increment-Feld "ID" existiert wäre das kein Problem (-> "SELECT FROM $table WHERE ID = mysql_insert_id();"), das auto_increment-Feld - falls überhaupt eines existiert - könnte aber auch einen anderen Namen tragen.

        Analysiere die Struktur der Tabelle. Es gibt das INFORMATION_SCHEMA.

        Verwunderte Grüße

        Vinzenz

        1. Hallo!

          Vielen Dank für eure Hilfe! Die Lösung ist dieser Hinweis mit INFORMATION_SCHEMA. So kann ich schauen, wie das auto_increment-Feld heisst und dann den gesamten Datensatz abfragen.

          Die Grundsätzliche Idee ist folgende (Bsp):

          $string = dbCreate('table', 'value=asdf, type=1', 'number');
          $string['success'] => [1/0 (Erfolg)]
          $string['value'] => [angeforderter Wert (hier: number) / MySQL-Error-String]

          Die Funktion erstellt einen neuen Datensatz in der angegebenen Tabelle mit den angegebenen Werten und gibt dann die angeforderten Werte zurück. Und dies soll für irgendwelche Tabellen gelten, auch wenn zB das auto_increment-Feld nicht "ID" sondern zB "number" heisst. (Mir ist klar, dass das keinen Sinn macht und man einheitliche Bezeichnungen wählen soll, aber wie gesagt arbeiten dann sehr viele Programmierer damit, mit allen möglichen Datenbankstrukturen)

          Vielen Dank & Liebe Grüsse,
          Thomas

          1. echo $begrüßung;

            $string = dbCreate('table', 'value=asdf, type=1', 'number');

            Diese Stelle sieht mir verdächtig nach einer vergessenen kontextgerechten Behandlung von Werten aus. Oder zerlegst du 'value=asdf, type=1' wieder in Einzelteile, um Bezeichnung und Wert kontextgerecht zu behandeln?

            echo "$verabschiedung $name";

            1. Hallo!

              Die Funktion ist Teil eines Systems, das u.a. gewisse Grundfunktionen bereitstellt. Ziel des Systems ist es, eine Grundlage für weitere Projekte zu bilden (zu deren einfacheren Realisierung). Deshalb muss die Funktion auch mit allen erdenklichen Tabellenstrukturen auskommen. Es handelt sich hierbei um eine Auftragsarbeit. Die Idee, solche Funktionen zu programmieren ist also nicht auf meinem Mist gewachsen. Aber danke für die Hinweise, ich werde diesbezüglich noch Abklärungen beim Auftraggeber starten.

              Diese Stelle sieht mir verdächtig nach einer vergessenen kontextgerechten Behandlung von Werten aus. Oder zerlegst du 'value=asdf, type=1' wieder in Einzelteile, um Bezeichnung und Wert kontextgerecht zu behandeln?

              Du meinst wohl, wegen der nicht vorhandenen Anführungs-/Schlusszeichen bei der Übergabe von String? Die muss ich wohl noch mit PHP einfügen müssen...

              Lg

              1. echo $begrüßung;

                Diese Stelle sieht mir verdächtig nach einer vergessenen kontextgerechten Behandlung von Werten aus. Oder zerlegst du 'value=asdf, type=1' wieder in Einzelteile, um Bezeichnung und Wert kontextgerecht zu behandeln?
                Du meinst wohl, wegen der nicht vorhandenen Anführungs-/Schlusszeichen bei der Übergabe von String? Die muss ich wohl noch mit PHP einfügen müssen...

                Da stellt sich gleich die nächste Frage: Was ist, wenn das nicht nur value=asdf heißt sondern 'value=as=df' oder 'value=as,df, type=1'? Du hast ja hier schon Feldnamen, Werte und Trennzeichen gemischt, ohne dass zu sehen ist, wie die Eindeutigkeit gewährleistet sein soll.

                echo "$verabschiedung $name";

                1. Da stellt sich gleich die nächste Frage: Was ist, wenn das nicht nur value=asdf heißt sondern 'value=as=df' oder 'value=as,df, type=1'? Du hast ja hier schon Feldnamen, Werte und Trennzeichen gemischt, ohne dass zu sehen ist, wie die Eindeutigkeit gewährleistet sein soll.

                  Stimmt, das gibt dann einen Syntax-Error. Dann werde ich wohl die Funktion so abändern müssen, dass man Anführungs- und Schlusszeichen setzen muss.

                  Lg

                  1. echo $begrüßung;

                    Da stellt sich gleich die nächste Frage: Was ist, wenn das nicht nur value=asdf heißt sondern 'value=as=df' oder 'value=as,df, type=1'? Du hast ja hier schon Feldnamen, Werte und Trennzeichen gemischt, ohne dass zu sehen ist, wie die Eindeutigkeit gewährleistet sein soll.

                    Stimmt, das gibt dann einen Syntax-Error. Dann werde ich wohl die Funktion so abändern müssen, dass man Anführungs- und Schlusszeichen setzen muss.

                    Und damit endet es nicht. Was ist, wenn diese Zeichen als Datenbestandteil auftauchen? Dann fängst du an, Maskierungen einzuführen. Spricht irgendwas dagegen, ein assoziatives Array zu übergeben/übernehmen statt eines Strings, den du erst aufwendig parsen müsstest. Dann kannst du auch NULL-Werte übergeben und musst dir nicht auch noch dafür eine unverwechselbare Schreibweise ausdenken, wenn später irgendjemand bemerkt, dass er NULLs braucht.

                    Das nächste Thema wären Ausdrücke. Sollen diese und damit auch Funktionen des DBMS verwendet werden können? Das kann sowohl beim SELECT als auch beim INSERT/UPDATE/DELETE eine Rolle spielen. Beim SELECT kann sich der Anwender vielleicht noch mit einer View behelfen. Beim Ändern muss man jedoch die Ausdrücke von einfachen Werten unterschieden können. Es in deinem bisherigen Ein-String-Ansatz mit unterzubringen erfordert weiteren Parse-Aufwand. Beim assoziativen Array kann man sich damit behelfen, dass der Wert kein String sondern ein Objekt der Klasse SQLExpression (beispielsweise).

                    Anwender entwickeln sich auch weiter. Irgendwann reichen denen einfache SQL-Statements nicht mehr und sie wollen zum Beispiel was mit mehr oder weniger komplizierten Joins anstellen und noch mehr syntaktische und funktionale Besonderheiten des DBMS ausreizen. Hast du darüber schon mal nachgedacht?

                    echo "$verabschiedung $name";

                    1. Salü!

                      Danke für deine vielen Hinweise! Ich werde die Funktion nun folgendermassen gestalten: Die übergebenen Werte sind so formatiert, dass der Befehl "INSERT INTO $table SET $content" (wobei: $table = z.B. 'testtable'; $content = z.B. "vlaue='Das ist ein String!', type=1" ) mit ihnen umgehen kann. Wie dann der Programmierer einen String formatiert bzw. wie er mit irgendwelchen speziellen Fällen umgeht, ist dann sein Problem.
                      Die einzige kleine Änderung die gegenüber der Vorgabe der Auftraggeber zu machen wäre, ist, dass ein String gleich schon bei der Übergabe in Anführungs- und Schlusszeichen gesetzt werden muss. Überhaupt macht ja alles andere keinen Sinn, schliesslich kann ja meine Funktion bei bestem Willen nicht wissen was zB mit 'value=as, df, type=1' gemeint ist. Ausserdem kann so der Programmierer selbst entscheiden welche Anführungs- und Schlusszeichen zu verwenden sind.
                      Die Funktion stellt ausserdem eine "Datenbank-Kernfunktion" dar, und wenn jemand irgendwelche speziellen Abfragen benötigt, kann dazu eine separate Funktion erstellt werden.

                      Danke für die Hilfe & Lg
                      Thomas

          2. Moin!

            Die Grundsätzliche Idee ist folgende (Bsp):

            $string = dbCreate('table', 'value=asdf, type=1', 'number');
            $string['success'] => [1/0 (Erfolg)]
            $string['value'] => [angeforderter Wert (hier: number) / MySQL-Error-String]

            Die Funktion erstellt einen neuen Datensatz in der angegebenen Tabelle mit den angegebenen Werten und gibt dann die angeforderten Werte zurück.

            Ich halte es für keine gute Idee, solch eine Funktion zur Verfügung zu stellen.

            Augenscheinlich bastelst du da ja irgendeinen DB-Access-Layer. Dann baust du mit Sicherheit auch eine Funktion ein, die einfach nur lesen kann.

            Das Problem ist, dass deine jetzt geplante Funktion mindestens zwei Querys an die Datenbank senden wird: Einmal ein INSERT, und dann ein SELECT. Da die Benennung der ID-Spalte nicht bekannt ist, werden außerdem noch weitere Querys zur Ermittlung des Namens benötigt.

            Diese Vorgehensweise erscheint machbar, wenn die Funktion einmal aufgerufen wird. Aber Datenbanken sind multitaskingfähig, also ist die Frage, wie dieser Ablauf reagiert, wenn parallel zu dieser Funktion noch andere Querys in den Daten herumwerkeln. Stichwort: Transaktionen!

            Um dieses Problem mußt du dir zwingend Gedanken machen, wenn du eine Funktion baust, die vorgibt, garantiert korrekte Daten zu liefern. Programmierer vergessen sowas sonst nämlich, und Race-Conditions sind mit die ekligsten Quellen für Bugs und Exploits, die man sich denken kann.

            Mit anderen Worten: Warum muß diese Funktion eierlegende Wollmilchsau spielen? Warum kann sie nicht einfach die erzeugte ID zurückgeben, mit der der Programmierer dann (weil er sein DB-Schema kennt) sofort einen SELECT nachschiebt.

            Wobei ich mich sowieso wundere, was dabei spannendes herauskommen soll! Entweder die Information ist im INSERT explizit genannt worden - dann wird die Antwort hoffentlich identisch sein. Oder die Information ist nicht im INSERT enthalten - dann wird der im DB-Schema definierte Default-Wert zurückkommen. Aber beide Informationen sind dem Programmierer bekannt, da er das DB-Schema kennt, was er verwendet und auf das er zugreift.

            Zusammengefaßt: Ich halte deine Funktion für potentiell gefährlich und von der Funktion her für überflüssig.

            - Sven Rautenberg

            --
            "Love your nation - respect the others."
            1. Hello,

              Wobei ich mich sowieso wundere, was dabei spannendes herauskommen soll! Entweder die Information ist im INSERT explizit genannt worden - dann wird die Antwort hoffentlich identisch sein. Oder die Information ist nicht im INSERT enthalten - dann wird der im DB-Schema definierte Default-Wert zurückkommen. Aber beide Informationen sind dem Programmierer bekannt, da er das DB-Schema kennt, was er verwendet und auf das er zugreift.

              Auf die Möglichkeit, dass noch ein Trigger (und stored Procedures) im Einsatz sein könnten, hat Vinzenz eben schon hingewiesen. Das, was man beim Insert angibt, muss nachher nicht in der Tabelle stehen.

              Liebe Grüße aus Syburg bei Dortmund

              Tom vom Berg

              --
              Nur selber lernen macht schlau
              http://bergpost.annerschbarrich.de
      2. Hello,

        Danke für deine Antwort. Das Problem ist, dass ich nach dem Eintragen den _gesamten_ Datensatz auslesen will, also nicht nur der Wert des auto_increment-Feldes. Ich denke das geht nur, indem man nach dem Eintragen wieder eine SELECT-Abfrage platziert. Das Problem ist: wie bekomme ich den zuletzt eingetragenen Eintrag einer Tabelle, deren Struktur völlig egal sein muss?

        Wenn Dein Insert in die Tabelle gerade eben funktioniert hat, dann kennst Du den letzten Datensatz ja noch. Du solltest Vertrauen zu Deinem Programm haben ;-)

        Wenn Du aber den zuletzt eingetragenen Datensatz von vor längerer Zeit haben willst, dann hilft Dir bei MySQL nur ein Timestamp, da der Auto-Increment-Wert angeblich nicht verlässlich hochzählt. Das wurde hier mehrfach diskutiert. Dies sollte, wenn man ihn tatsächlich als Autoincrement-Wert verwendet, und nicht vorgibt beim Insert, aber besser der Fall sein.

        Vielleicht liegt dieses Manquo in Standard-SQL begründet? Ich weiß es leider nicht.

        Um das so leidlich zu beheben, kannst Du einen Timestmp setzen. Da die Granularität aber eine Sekunde ist, ist das mMn noch unsicherer. Es können durchaus mal 100 Datensätze mit demselben Timestamp eingetragen worden sein, z.B. bei einer Select-from-<table>-Anweisung.

        Ich persönlich würde immer einen Strict-Auto-Increment-Wert benutzen, um den letzen Datensatz zu ermitteln und habe bisher damit auch noch keine Probleme gehabt. Vielleicht ist das mit der Unbestimmtheit dieses Wertes auch nur ein Mythos? Das DBMS wäre dann ja schließlich unbrauchbarer Schrott!

        Allerdings musst Du trotzdem beachten, dass zwischen dem Auslesen und dem Verwenden der Werte Zeit vergeht. Es ist also nicht richtig, die in einer nicht atomar gekapselten Operation wieder zu verwenden. Du müsstest also ggf. die bezogene Tabelle solange sperren, bis die Werte ausgelesen, verarbeitet und wieder weggeschrieben sind. Das ist ungünstig.

        Hier wird vermutlich ein Subselect der bessere Wert sein, aber ich weiß nicht, ob das immer atomar gekapselt wird.

        Um für Deine Aufgabenstellung also eine Lösung zu finden, ohne dass sie sich aufbläst zu einer unlösbaren, soltest Du also mal _genauestens_ beschreiben, was Du eigentlich erreichen willst.

        Liebe Grüße aus Syburg bei Dortmund

        Tom vom Berg

        --
        Nur selber lernen macht schlau
        http://bergpost.annerschbarrich.de
        1. Moin!

          Wenn Du aber den zuletzt eingetragenen Datensatz von vor längerer Zeit haben willst, dann hilft Dir bei MySQL nur ein Timestamp, da der Auto-Increment-Wert angeblich nicht verlässlich hochzählt.

          Du verbreitest Gerüchte und Fehlinformationen. Warum?

          Wenn du belastbare Belege für die Behauptung hast, dass auto_increment in MySQL fehlerhaft arbeitet, dann gib deine Quellen an.

          Wenn nein, dann unterlasse dieses Gerüchteverbreiten.

          Fakt ist: auto_increment arbeitet exakt im Rahmen seiner Spezifikation. Würde es das nicht tun, so ist mit Sicherheit davon auszugehen, dass das a) bereits bemerkt worden wäre (wenn nicht von MySQL selbst, dann von den Usern) und b) wäre es ein Bug, der zu beheben ist, und kein akzeptables Verhalten.

          In jedem Fall ist aber dein Ratschlag mit dem Timestamp mal komplett für's Klo!

          - Sven Rautenberg

          --
          "Love your nation - respect the others."
          1. Hello,

            Wenn Du aber den zuletzt eingetragenen Datensatz von vor längerer Zeit haben willst, dann hilft Dir bei MySQL nur ein Timestamp, da der Auto-Increment-Wert angeblich nicht verlässlich hochzählt.

            Du verbreitest Gerüchte und Fehlinformationen. Warum?

            Wenn du belastbare Belege für die Behauptung hast, dass auto_increment in MySQL fehlerhaft arbeitet, dann gib deine Quellen an.

            Wenn nein, dann unterlasse dieses Gerüchteverbreiten.

            Das Forumsarchiv kannst Du doch schon selber durchsuchen, oder?
            Das ist mir jetzt zu dumm!
            Oder sind die nun plötzlich als Falschinformation hingestellten Aussagen schon aus dem Archiv gelöscht inzwischen?

            Also ich bin echt sauer auf Dich jetzt!

            Liebe Grüße aus Syburg bei Dortmund

            Tom vom Berg

            --
            Nur selber lernen macht schlau
            http://bergpost.annerschbarrich.de
            1. Moin!

              Wenn Du aber den zuletzt eingetragenen Datensatz von vor längerer Zeit haben willst, dann hilft Dir bei MySQL nur ein Timestamp, da der Auto-Increment-Wert angeblich nicht verlässlich hochzählt.

              Du verbreitest Gerüchte und Fehlinformationen. Warum?

              Wenn du belastbare Belege für die Behauptung hast, dass auto_increment in MySQL fehlerhaft arbeitet, dann gib deine Quellen an.

              Wenn nein, dann unterlasse dieses Gerüchteverbreiten.

              Das Forumsarchiv kannst Du doch schon selber durchsuchen, oder?

              "auto_increment" liefert 831 Suchergebnisse. Die werde ich nicht alle angucken, um eine Aussage zu finden, deren Existenz ich anzweifle. Das wäre deine Aufgabe. Denn du sagst ja selbst "Gerücht" dazu - argumentierst aber sofort danach mit dem Timestamp so, als wäre es die Wahrheit.

              "auto_increment zählt falsch" liefert 5 Suchergebnisse, die allesamt den Fragesteller darüber aufklären, dass die ID nicht fortlaufend zählt, sondern identifiziert.

              Das ist mir jetzt zu dumm!
              Oder sind die nun plötzlich als Falschinformation hingestellten Aussagen schon aus dem Archiv gelöscht inzwischen?

              Dein impliziter Vorwurf, wir würden, von langer Hand vorbereitet, das Archiv "aufräumen", nur damit du ausgerechnet jetzt keinen Beleg mehr für deine Gerüchteverbreitung findest, ist absurd.

              Also ich bin echt sauer auf Dich jetzt!

              Damit kann ich leben.

              Womit ich nicht leben kann, ist die wissentliche Gerüchteverbreitung und Darstellung absolut untauglicher Alternativen ("Timestamp"). Damit richtest du bei unerfahrenen Programmieranfängern mehr Schaden an (wenn sie diese Alternative nutzen), als wenn diese dann irgendwann tatsächlich mal auf einen Bug in MySQL stoßen würden (weil das Gerücht in irgendeiner MySQL-Version tatsächlich stimmt).

              Vielleicht hältst du dich mit aufsehenerregenden Aussagen und konträren Ansichten zu anerkannten Verfahrensweisen einfach ein wenig zurück, wenn dir Belege und unterstützende Aussagen fehlen oder du keine Lust hast, diese auf Anfrage zu recherchieren.

              Deine unspezifizierten Aussagen zur OOP ganz unten harren ja auch immer noch einer schon mehrfach von dir angekündigten, aber bislang ausgebliebenen, ausführlichen Antwort. Und sowas geht mir ganz gehörig auf den Senkel: Maul auf reißen, aber nichts dahinter.

              - Sven Rautenberg

              --
              "Love your nation - respect the others."
              1. Hello,

                Womit ich nicht leben kann, ist die wissentliche Gerüchteverbreitung und Darstellung absolut untauglicher Alternativen ("Timestamp"). Damit richtest du bei unerfahrenen Programmieranfängern mehr Schaden an (wenn sie diese Alternative nutzen), als wenn diese dann irgendwann tatsächlich mal auf einen Bug in MySQL stoßen würden (weil das Gerücht in irgendeiner MySQL-Version tatsächlich stimmt).

                Sag mal, was soll das?
                Ich habe erklärt, dass Timestamp ungeeignet ist.

                Nun ist endlich einer aus dem Koma aufgewacht und vertritt meine schon lange Jahre vertretene, und geht trotzdem auf mich los? ICH bin doch der, der immer gesagt hat, Timestamp ist ungeeignet, weil zu grob, und autoincrement muss funktionieren, wenn die Entwickler nicht total verblödet sind!

                Also lass mich bitte mit Deinen vollkommen unsinnigen Verdrehungen in Ruhe.
                Prügeln können wir uns nächstes Wochende ;-)

                Also nochmal zur Wiederholung:
                Eine Autoincrement-Spalte ist das passende Mittel, weil sie sicher hochzählt, wenn man nicht selber daran herummanipuliert hat. Ich rechne nicht damit, dass sich das bei MySQL irgendwann mal ändert, das wäre der Tod für das DBMS.

                Timestamp ist KEIN geeignter Spaltentyp, um den letzten Eintrag in eine Tabelle zu finden. Es könnten mehrere Datensätze denselben Timestamp haben.

                Und das jemand einen Unique-Index auf eine Timestamp-Spalte setzt, wäre zwar vielelicht möglich, habe ich aber noch nie gesehen udn würde es auch selber nicht tun. Ich hoffe sogar, dass das gar nicht geht.

                Liebe Grüße aus Syburg bei Dortmund

                Tom vom Berg

                --
                Nur selber lernen macht schlau
                http://bergpost.annerschbarrich.de
                1. Hallo Tom,

                  Und das jemand einen Unique-Index auf eine Timestamp-Spalte setzt, wäre zwar vielelicht möglich, habe ich aber noch nie gesehen udn würde es auch selber nicht tun. Ich hoffe sogar, dass das gar nicht geht.

                  Warum? Selbstverständlich geht das. Ein schneller Test mit dem von Dir bevorzugten Frontend oder handgeschriebenem SQL-Code hätte Dir das gezeigt.

                  Freundliche Grüße

                  Vinzenz

          2. Hello,

            http://forum.de.selfhtml.org/archiv/2002/12/t33517/#m182504

            Diese Aussage stammt also nicht von mir, sondern wurde von Anderen in die Welt gesetzt und u.a. auch von Dir unterstützt.

            ICH habe mich immer dagegen verwehrt, dass ein autoincrement_key nicht sauber hochzählt, wenn man es nicht ausdrücklich von ihm verlangt. Das DBMS wäre dann Schrott. Dass MySQL das explizite Setzen bei einem autoincremt erlaubt, ist schon grenzwertig genug.

            Dass es DBMS gibt, die gar kein Autoincrement unterstützten, ist deren Problem.

            Liebe Grüße aus Syburg bei Dortmund

            Tom vom Berg

            --
            Nur selber lernen macht schlau
            http://bergpost.annerschbarrich.de
            1. Moin!

              http://forum.de.selfhtml.org/archiv/2002/12/t33517/#m182504

              Diese Aussage stammt also nicht von mir, sondern wurde von Anderen in die Welt gesetzt und u.a. auch von Dir unterstützt.

              In dem verlinkten Thread habe ich mich gar nicht geäußert.

              Abgesehen davon wird deutlich, dass du Cheatahs Aussage nicht verstanden hast.

              ICH habe mich immer dagegen verwehrt, dass ein autoincrement_key nicht sauber hochzählt, wenn man es nicht ausdrücklich von ihm verlangt.

              Aber genau das ist doch der Fall.

              Das DBMS wäre dann Schrott. Dass MySQL das explizite Setzen bei einem autoincremt erlaubt, ist schon grenzwertig genug.

              Ja und? Primärschlüssel sind immer eindeutig, wer absichtlich darin rumwurschtelt, weiß entweder, was er tut, oder landet auf der Nase.

              Dass es DBMS gibt, die gar kein Autoincrement unterstützten, ist deren Problem.

              Lenk' nicht ab, es geht um MySQL und dort um auto_increment.

              - Sven Rautenberg

              --
              "Love your nation - respect the others."
            2. echo $begrüßung;

              http://forum.de.selfhtml.org/archiv/2002/12/t33517/#m182504

              Wenn es darum geht, dass auto_increment am Ende der Skala einfach immer die gleichen Werte liefert, so hab ich unter MySQL 5.0.60 folgendes ermittelt:

              CREATE TABLE IF NOT EXISTS test (
                  foo tinyint(3) unsigned NOT NULL auto_increment,
                  bar varchar(10) NOT NULL,
                  PRIMARY KEY  (foo)
                ) AUTO_INCREMENT=254

              Der auto_increment-Wert steht auf 254 und symbolisiert damit, dass schon 253 IDs "verbraucht" sind. Die Spalte foo ist als (vorzeichenloses) TINYINT absichtlich viel zu klein gewählt, um das Verhalten zu demonstrieren.

              INSERT INTO test (bar) VALUES
                ('Tom'),
                ('Sven'),
                ('SELFHTML')

              fügt Tom (254) und Sven (255) ein und verabschiedet sich dann mit einem »Duplicate entry '255' for key 1«. Der auto_increment-Wert in der Tabellenstruktur steht auf 256 und bewegt sich auch bei weiteren Insert-Versuchen nicht weiter nach oben. Die Versuche schlagen jedoch alle mit der bereits erwähnten Fehlermeldung fehl (ja, 255, trotz der anderswo stehenden 256).

              Zum Verhalten von auto_increment am Ende des Universums fand ich im MySQL-Handbuch keine Aussage.

              Mein Fazit: Wer seine Spalten mit unangemessenem Wertebereich wählt, ist selbst Schuld. Wenn er dann noch Fehlermeldungen ignorieren sollte, ...

              echo "$verabschiedung $name";

              1. Hello Dedlfix,

                CREATE TABLE IF NOT EXISTS test (
                    foo tinyint(3) unsigned NOT NULL auto_increment,
                    bar varchar(10) NOT NULL,
                    PRIMARY KEY  (foo)
                  ) AUTO_INCREMENT=254

                Der auto_increment-Wert steht auf 254 und symbolisiert damit, dass schon 253 IDs "verbraucht" sind. Die Spalte foo ist als (vorzeichenloses) TINYINT absichtlich viel zu klein gewählt, um das Verhalten zu demonstrieren.

                INSERT INTO test (bar) VALUES
                  ('Tom'),
                  ('Sven'),
                  ('SELFHTML')

                Danke für den Test. :-)

                Und man sollte daran denken, dass man den Wertebereich weder mit PHP noch mit der C-API voll ausschöpfen kann. Ich habe jetzt aber noch nicht nachgeschaut, ob es tatsächlich int ist, was benutzt wird, oder ob es unsigned int ist. In PHP ist es wohl nur int?

                Liebe Grüße aus Syburg bei Dortmund

                Tom vom Berg

                --
                Nur selber lernen macht schlau
                http://bergpost.annerschbarrich.de
      3. Hello,

        um den Namen der Primary-Key-Spalte zu erfragen, habe ich im Rahmen eines Projektes mal eine Funktion geschrieben.
        Die ist inzwischen allerdings überholt, da es das information_schema heute gibt und überarbeitet Abfrage-Funktionen.

        http://forum.de.selfhtml.org/archiv/2004/4/t79418/#m460076

        Aber vielleicht wird Dir so klar, worum es ging und Du kannst es mit einem komplexeren Select auf das information_schema erledingen.

        Liebe Grüße aus Syburg bei Dortmund

        Tom vom Berg

        --
        Nur selber lernen macht schlau
        http://bergpost.annerschbarrich.de
        1. echo $begrüßung;

          um den Namen der Primary-Key-Spalte zu erfragen,

          Da ein Index - und das gilt auch für den Primärschlüssel - auch aus mehreren Feldern bestehen kann ist die auto_increment-Spalte nur dann auch der Primärschlüssel, wenn der Primärschlüssel nur auf genau einer Spalte liegt.

          Die ist inzwischen allerdings überholt, da es das information_schema heute gibt und überarbeitet Abfrage-Funktionen.
          http://forum.de.selfhtml.org/archiv/2004/4/t79418/#m460076

          Außerdem arbeitet sie falsch, weil sie o.g. nicht berücksichtigt.

          echo "$verabschiedung $name";

      4. echo $begrüßung;

        Das Problem ist, dass ich nach dem Eintragen den _gesamten_ Datensatz auslesen will, also nicht nur der Wert des auto_increment-Feldes. Ich denke das geht nur, indem man nach dem Eintragen wieder eine SELECT-Abfrage platziert. Das Problem ist: wie bekomme ich den zuletzt eingetragenen Eintrag einer Tabelle, deren Struktur völlig egal sein muss?

        Jetzt. Problem erkannt. Der Name des auto_increment-Feldes ist in der Tabellenstruktur hinterlegt, die du auswerten müsstest. Dazu gibt es einerseits die von Vinzenz erwähnte INFORMATION_SCHEMA-Datenbank. Dort wäre die Tabelle COLUMNS interessant. Im Feld EXTRA steht bei der auto_increment-Spalte ebendies drin. Die gleiche Angabe ist auch in einem der SHOW-Statements zu finden. Wenn dir nur eine MySQL-Version kleiner als 5 zur Verfügung steht, ist das die einzige Möglichkeit.

        echo "$verabschiedung $name";

      5. Moin!

        Danke für deine Antwort. Das Problem ist, dass ich nach dem Eintragen den _gesamten_ Datensatz auslesen will, also nicht nur der Wert des auto_increment-Feldes. Ich denke das geht nur, indem man nach dem Eintragen wieder eine SELECT-Abfrage platziert. Das Problem ist: wie bekomme ich den zuletzt eingetragenen Eintrag einer Tabelle, deren Struktur völlig egal sein muss?

        Ich sehe irgendwie nicht so ganz dein Problem.

        Entweder hat deine Funktion definiert bekommen, wie die Tabellenstruktur der verwendeten Datenbank aussieht. Dann weiß sie deshalb auch, welche Spalte die ID-Spalte ist, und kann dieses Wissen für ein nachfolgendes SELECT nutzen.

        Oder deine Funktion weiß nichts über die Tabellenstruktur. Dann muß sie sich drauf verlassen, dass der Funktionsaufrufende diese Kenntnis hat, und kann dann von diesem zusätzlich anfordern, dass er die ID-Spalte als weiteren Parameter übergibt.

        Schließlich mußt du dich ja sowieso drauf verlassen, dass auch die Felder für die übergebenen Werte sowie die dann auszulesenden Felder in der Tabelle schon existieren. Ansonsten kriegst du beim Abschicken des Querys einen Fehler um die Ohren und hast den Aufrufer darüber zu informieren.

        Wenn man zum Beispiel wüsste, dass in der Tabelle das auto_increment-Feld "ID" existiert wäre das kein Problem (-> "SELECT FROM $table WHERE ID = mysql_insert_id();"), das auto_increment-Feld - falls überhaupt eines existiert - könnte aber auch einen anderen Namen tragen.

        Mir sind Anwendungsfälls suspekt, bei denen angeblich die totale Flexibilität herrschen soll. Eine Applikation benötigt ein festgelegtes Datenmodell, ansonsten kann man damit nicht arbeiten. Und selbst wenn es um eine Applikation geht, die ein vom Anwender definierbares Datenmodell haben soll, wird man in solchen Fällen programmierseitig dann ein festes Datenmodell für das flexible Datenmodell bauen.

        Ausnahmefälle hierfür sind in meinen Augen wirklich nur so Anwendungen wie Datenbank-Admin-Programme (phpMyAdmin), deren Aufgabe einfach von einer anderen Qualität ist, und die aber eigentlich die gesamte Verantwortung für das erfolgreiche Gelingen der vom Anwender initiierten Aktionen auf den Anwender abwälzen, und nur den "zufällig" erfolgreichen Query als Tabelle zurückliefern, andernfalls aber auch nur die Fehlermeldung der Datenbank, und nichts sonst.

        Solch ein Verhalten ist in anwenderfreundlichen Applikationen für den Nicht-SQL-Könner aber nur bis zu einem gewissen Level möglich - in irgendeiner Schicht der Applikation muß die Fehlermeldung der DB irgendwie in eine vernünftige Reaktion an den Anwender transformiert werden.

        - Sven Rautenberg

        --
        "Love your nation - respect the others."
        1. Hello,

          Mir sind Anwendungsfälls suspekt, bei denen angeblich die totale Flexibilität herrschen soll. Eine Applikation benötigt ein festgelegtes Datenmodell, ansonsten kann man damit nicht arbeiten. Und selbst wenn es um eine Applikation geht, die ein vom Anwender definierbares Datenmodell haben soll, wird man in solchen Fällen programmierseitig dann ein festes Datenmodell für das flexible Datenmodell bauen.

          Datenbank-Tools wie phpMyAdmin, sql-front oder Heidi-SQL sind Dir also suspekt. Das erstaunt mich doch einigermaßen!

          Liebe Grüße aus Syburg bei Dortmund

          Tom vom Berg

          --
          Nur selber lernen macht schlau
          http://bergpost.annerschbarrich.de
          1. Hallo Tom,

            Mir sind Anwendungsfälls suspekt, bei denen angeblich die totale Flexibilität herrschen soll. Eine Applikation benötigt ein festgelegtes Datenmodell, ansonsten kann man damit nicht arbeiten. Und selbst wenn es um eine Applikation geht, die ein vom Anwender definierbares Datenmodell haben soll, wird man in solchen Fällen programmierseitig dann ein festes Datenmodell für das flexible Datenmodell bauen.

            Datenbank-Tools wie phpMyAdmin, sql-front oder Heidi-SQL sind Dir also suspekt. Das erstaunt mich doch einigermaßen!

            ???
            ich dachte, Du könntest lesen. Ich dachte, dass Du einen Beitrag zuerst komplett liest, bevor Du darauf antwortest. Ich dachte, wenigstens beim Löschen wäre Dir der Folgeabschnitt, auf den Du Dich beziehst ins Auge gefallen. Ich zitiere Sven gerne extra für Dich:

            Ausnahmefälle hierfür sind in meinen Augen wirklich nur so Anwendungen wie Datenbank-Admin-Programme (phpMyAdmin), deren Aufgabe einfach von einer anderen Qualität ist, und die aber eigentlich die gesamte Verantwortung für das erfolgreiche Gelingen der vom Anwender initiierten Aktionen auf den Anwender abwälzen, und nur den "zufällig" erfolgreichen Query als Tabelle zurückliefern, andernfalls aber auch nur die Fehlermeldung der Datenbank, und nichts sonst.

            Daraus schließe ich, dass Sven Datenbank-Tools wie phpMyAdmin oder MySQL Query Browser *nicht* suspekt sind.

            Erstaunte Grüße

            Vinzenz

    2. Hello,

      Ist es irgendwie möglich, den Namen des auto_increment-Feldes einer Tabelle auszulesen?

      Es kann in einer Tabelle nur ein auto_increment-Feld geben. mysql(i)_insert_id() liefert den Wert genau dieses Feldes. Dessen Name ist unerheblich.

      Das funktioniert sicher aber nur _genau_ _nach_ dem Insert über die Connection.
      Ich habe den Eindruck, dass Thomas diese ID aber vorher haben will.
      Dann ist vermutlich das Konzept falsch.

      Liebe Grüße aus Syburg bei Dortmund

      Tom vom Berg

      --
      Nur selber lernen macht schlau
      http://bergpost.annerschbarrich.de
      1. echo $begrüßung;

        Es kann in einer Tabelle nur ein auto_increment-Feld geben. mysql(i)_insert_id() liefert den Wert genau dieses Feldes. Dessen Name ist unerheblich.
        Das funktioniert sicher aber nur _genau_ _nach_ dem Insert über die Connection.
        Ich habe den Eindruck, dass Thomas diese ID aber vorher haben will.
        Dann ist vermutlich das Konzept falsch.

        Wenn das so wäre, könnte man beispielsweise die aus Oracle bekannten Sequenzen nachbilden. Eine Beispiel-Implementation für MySQL findet sich in den MySQL-Treibern der PEAR-Pakete DB und MDB2. (Letzterer bietet auch ein currID() an, aber das hat ein Nebenläufigkeitsproblem, wenn man nicht zusätzlich noch für Table-Locking sorgt.)

        echo "$verabschiedung $name";