Jan: Mysql Auto-Increment-Wert sofort nutzen

Hallo,

Eine Tabelle in einer Mysql-DB bestehen aus 2 Felder.

Tabelle = tbl1
id - integer - auto increment
feld1 - varchar

Ich dachte es wäre vielleicht möglich den gerade automatisch erzeugten Wert "id" auch in ein anderes feld zu portieren.

insert into tbl1 (feld1)values(id);

Doch das geht nicht, der Eintrag findet zwar statt aber mit der Zahl 0.
* Nebenbei, habs auch mit sqlite probiert, da gibts dann nicht mal einen Eintrag.

Warum geht das nicht und gibt es eine Alternative?
Ohne erst den kompletten Insert-Query zu durchlaufen und dann erst den Wert "id" abzufragen um dann im feld1 ein update zu machen, also sozusagen lieber in einem Rutsch.

Jan

  1. Hi,

    Tabelle = tbl1
    id - integer - auto increment
    feld1 - varchar

    Ich dachte es wäre vielleicht möglich den gerade automatisch erzeugten Wert "id" auch in ein anderes feld zu portieren.

    insert into tbl1 (feld1)values(id);

    Noch im gleichen Statement?
    Das ist m.W. nicht moeglich -

    Warum geht das nicht

    • weil das Statement erst mal ausgefuehrt sein muss, bevor feststeht, welche ID vergeben wurde.

    und gibt es eine Alternative?

    Wenn du mal beschreibst, was dich ueberhaupt veranlasst, den Wert innerhalb des Datensatzes doppelt vorhalten zu wollen - dann findet sich vielleicht eine.

    MfG ChrisB

    1. Hi,

      Warum geht das nicht

      • weil das Statement erst mal ausgefuehrt sein muss, bevor feststeht, welche ID vergeben wurde.

      »»
      hmmm, doch ich könnte zb im gleichen Query last_insert_id auslesen und +1 setzen, aber das wäre nur ein Notlösung und ich bin mir nicht sicher ob da nicht schneller Konflikte im regen Betrieb passieren können.

      und gibt es eine Alternative?

      Wenn du mal beschreibst, was dich ueberhaupt veranlasst, den Wert innerhalb des Datensatzes doppelt vorhalten zu wollen - dann findet sich vielleicht eine.

      Erstmal nur zu Testzwecken, aber Gründe gäbe es einige, die aber nichts mit der Frage zu tun haben. Zb. Passwortgenerierung aus  Kombi irgendeines Wertes und der id im Falle von CONCAT. Aber wie gesagt, es geht hier nicht um eine spezielle Lösung, sondern nur um das Wissen einer Möglichkeit.

      Danke
      Jan

      1. Moin!

        Warum geht das nicht

        • weil das Statement erst mal ausgefuehrt sein muss, bevor feststeht, welche ID vergeben wurde.
          »»
          hmmm, doch ich könnte zb im gleichen Query last_insert_id auslesen und +1 setzen, aber das wäre nur ein Notlösung und ich bin mir nicht sicher ob da nicht schneller Konflikte im regen Betrieb passieren können.

        Das, was dir last_insert_id ausgibt (also wahlweise durch SQL abgefragt, Funktion LAST_INSERT_ID(), oder durch den DB-Client, der diese Info auch "direkt" zurückgeben kann, in PHP z.B. mysql_insert_id() ), ist die ID, die beim INSERT erzeugt wurde - wenn du es denn ausgeführt hast. Diese ID kannst du abfragen und speichern und bei weiteren INSERTs verwenden.

        last_insert_id + 1 ist allerdings Schwachsinn. Die Datenbank triff Vorkehrungen, dass du garantiert immer genau die ID kriegst, die auf der derzeitigen DB-Connection erzeugt wurde - weil das ja parallel auf mehreren Connections passieren könnte, wenn das Skript (oder unterschiedliche Skripte) von mehreren Nutzern gleichzeitig aufgerufen wird. Würdest du einfach eine Eins addieren, würdest du garantiert Müll erzeugen.

        - Sven Rautenberg

        --
        "Love your nation - respect the others."
        1. Hallo Sven,

          last_insert_id + 1 ist allerdings Schwachsinn. Die Datenbank triff Vorkehrungen, dass du garantiert immer genau die ID kriegst, die auf der derzeitigen DB-Connection erzeugt wurde - weil das ja parallel auf mehreren Connections passieren könnte, wenn das Skript (oder unterschiedliche Skripte) von mehreren Nutzern gleichzeitig aufgerufen wird. Würdest du einfach eine Eins addieren, würdest du garantiert Müll erzeugen.

          Nicht ganz, das war nur nicht passend zu dem Beispielquery hier.
          Bei meinem echten realen Test, sind es 2 Inserts und da gibt mysql mit last_insert_id nur die erste ID aus. Also +1

          Jan

          1. Hallo Jan,

            Nicht ganz, das war nur nicht passend zu dem Beispielquery hier.

            ?

            Bei meinem echten realen Test, sind es 2 Inserts und da gibt mysql mit last_insert_id nur die erste ID aus. Also +1

            Du meinst _eine_ INSERT-Anweisung, die mehrere Zeilen einfügt. Ja sicher, das ist das dokumentierte Verhalten, siehe Markierung "Important".

            Freundliche Grüße

            Vinzenz

  2. Hi,
    ich habe es jetzt mal anders probiert.

    #Tabelle muell - 2 Felder - id= auto increment

    insert into muell (abc)values('xxx');#  Betroffene Datensätze:  1
    update muell set abc=concat('xyz',id);#  Betroffene Datensätze:  1

    Soweit funktioniert das auch, aber ein paar Fragen bleiben.

    Ist diese Vorgehensweise überhaupt in Ordnung?

    update muell set abc=concat('xyz',id);#  Betroffene Datensätze:  1
    Warum muss ich hier keine where-Bedingung angeben, bezieht sich das immer automatisch auf die letzte Anweisung?

    update muell set abc=id;#  Betroffene Datensätze:  23
    Ohne concat sollen auf einmal alle Datensättze betroffen sein?
    Dabei ist das Ergebnis in Ordnung und nur der letzte Eintrag wurde verändert.

    Warum funktioniert die Concat-Variante nicht bei sqlite?

    Jan

    1. Betreff letztes Posting:
      Irgendet etwas stimmt hier nicht, die Ausgaben im letzten Posting sind nicht wiederholbar, jetzt sind doch alle Einträge betroffen, egal ob concat oder nicht. Muss noch ein wenig mehr testen.

      Jan

      1. Aha, jetzt kommen wir der Sache näher. Da sich der Wer im Feld "abc" nicht geändert hätte, gab die Rueckmeldung von update auch nur den aktuellen Eintrag raus.

        Also betroffene Feldänderungen = 1
        Das wusst ich bisher auch nicht, dass mysql prüft ob etwas zu ändern ist, dachte wird immer automatisch überschrieben auch wenn gleich.

        Na gut dann nächster Versuch:
        insert into muell (abc)values('xyxy');update muell set abc=last_insert_id();

        Geht, aber natürlich wieder leider auf alle Einträge.

        insert into muell (abc)values('xyxy');update muell set abc=last_insert_id() where id=last_insert_id();
        Das geht nicht, obwohl keine Fehlermedlung kommt, denke das in dem Fall eben die wherebedingung nichts finden kann, weil vermutlich last_insert_id=0 sein könnte.

        Wobei ich die Logik nicht verstehe, schliesslich findet er ja auch den richtigen Wert ohne "where".

        Wie würdet ihr diese Abfrage gestalten, mal vom Sinn/Unsinn des Ganzen abgesehen?

        Jan

        1. Moin!

          Aha, jetzt kommen wir der Sache näher. Da sich der Wer im Feld "abc" nicht geändert hätte, gab die Rueckmeldung von update auch nur den aktuellen Eintrag raus.

          Wenn ich dich so beobachte, habe ich allerdings nicht den Eindruck, du kämst irgendwas näher. :)

          Also betroffene Feldänderungen = 1
          Das wusst ich bisher auch nicht, dass mysql prüft ob etwas zu ändern ist, dachte wird immer automatisch überschrieben auch wenn gleich.

          Das kann man selbst bestimmen. Standardmäßig meldet MySQL nur echte Veränderungen zurück, es kann aber auch alle Datensätze zählen, die insgesamt unter die WHERE-Klausel fallen.

          Na gut dann nächster Versuch:
          insert into muell (abc)values('xyxy');update muell set abc=last_insert_id();

          Das Update setzt in ALLEN Datensätzen der Tabelle die Spalte abc auf den ID-Wert des letzten Inserts. Das kann nicht sein, was du willst. Aber was willst du denn eigentlich überhaupt? Es scheint mir wenig sinnvoll, die ID zu duplizieren.

          Geht, aber natürlich wieder leider auf alle Einträge.

          Logisch. Wo soll die ID denn hin?

          insert into muell (abc)values('xyxy');update muell set abc=last_insert_id() where id=last_insert_id();
          Das geht nicht, obwohl keine Fehlermedlung kommt, denke das in dem Fall eben die wherebedingung nichts finden kann, weil vermutlich last_insert_id=0 sein könnte.

          Welchen Sinn hat diese Konstruktion?

          Und bitte geh dabei mal von deinem Müllbeispiel ab und komme auf deine reale Anwendung, bei der sowas sinnvoll sein soll. Denn es ist in meinen Augen absolut NICHT sinnvoll, ein ID-Feld im gleichen Datensatz zu duplizieren.

          Wobei ich die Logik nicht verstehe, schliesslich findet er ja auch den richtigen Wert ohne "where".

          Wie würdet ihr diese Abfrage gestalten, mal vom Sinn/Unsinn des Ganzen abgesehen?

          Ich würde nicht vom Unsinn absehen und sie deshalb nicht gestalten. :)

          - Sven Rautenberg

          --
          "Love your nation - respect the others."
          1. Hallo Sven,

            Aha, jetzt kommen wir der Sache näher. »»
            Wenn ich dich so beobachte, habe ich allerdings nicht den Eindruck, du kämst irgendwas näher. :)

            ohne echte Hilfe offensichtlich nicht.

            Also betroffene Feldänderungen = 1
            Das wusst ich bisher auch nicht, dass mysql prüft ob etwas zu ändern ist, dachte wird immer automatisch überschrieben auch wenn gleich.

            Das kann man selbst bestimmen. Standardmäßig meldet MySQL nur echte Veränderungen zurück, es kann aber auch alle Datensätze zählen, die insgesamt unter die WHERE-Klausel fallen.

            Ja das bedeutet also tatsächlich, MySql ändert keine Werte, was im umkehrschluss bedeutet MySql prüft ob geändert werden muss.

            Na gut dann nächster Versuch:
            insert into muell (abc)values('xyxy');update muell set abc=last_insert_id();

            Das Update setzt in ALLEN Datensätzen der Tabelle die Spalte abc auf den ID-Wert des letzten Inserts. Das kann nicht sein, was du willst. Aber was willst du denn eigentlich überhaupt? Es scheint mir wenig sinnvoll, die ID zu duplizieren.

            Natürlich, aber das sagte ich direkt im folgenden Satz selber.

            Geht, aber natürlich wieder leider auf alle Einträge.

            Logisch. Wo soll die ID denn hin?

            Eben, sage ich ja selber.

            insert into muell (abc)values('xyxy');update muell set abc=last_insert_id() where id=last_insert_id();
            Das geht nicht, obwohl keine Fehlermedlung kommt, denke das in dem Fall eben die wherebedingung nichts finden kann, weil vermutlich last_insert_id=0 sein könnte.

            Welchen Sinn hat diese Konstruktion?

            Dazu komme ich noch.

            Und bitte geh dabei mal von deinem Müllbeispiel ab und komme auf deine reale Anwendung, bei der sowas sinnvoll sein soll. Denn es ist in meinen Augen absolut NICHT sinnvoll, ein ID-Feld im gleichen Datensatz zu duplizieren.

            Jeder hat halt andere Ansprüche.

            Wobei ich die Logik nicht verstehe, schliesslich findet er ja auch den richtigen Wert ohne "where".

            Das bleibt immer noch unbeatwortet.

            Wie würdet ihr diese Abfrage gestalten, mal vom Sinn/Unsinn des Ganzen abgesehen?

            Ich würde nicht vom Unsinn absehen und sie deshalb nicht gestalten. :)

            Gut, vielleicht findet sich ja Jemand mit mehr Experimentierfreude.

            Und um mal den Nutzen darzustellen.
            Im Moment (ist auch nur reine Experimentierlust), versuche ich eine Prüfsumme aus mehreren Feldern zu erzeugen die allerdings auch die ID beinhält.

            So brauche ich bei einer Abfrage nicht viele Felder abzufragen und die Prüfsumme sozusagen jedes Mal neu erstellen zu lassen, nein ich brauche dann lediglich ein einziges Feld abzufragen.

            Wenn das in deinen Augen Unsinn ist, sag doch mal warum.

            Jan

            1. Moin!

              Und um mal den Nutzen darzustellen.
              Im Moment (ist auch nur reine Experimentierlust), versuche ich eine Prüfsumme aus mehreren Feldern zu erzeugen die allerdings auch die ID beinhält.

              So brauche ich bei einer Abfrage nicht viele Felder abzufragen und die Prüfsumme sozusagen jedes Mal neu erstellen zu lassen, nein ich brauche dann lediglich ein einziges Feld abzufragen.

              Wenn das in deinen Augen Unsinn ist, sag doch mal warum.

              Was soll die Prüfsumme denn bewirken? Und hast du schon mal was von Indices gehört?

              - Sven Rautenberg

              --
              "Love your nation - respect the others."
              1. So brauche ich bei einer Abfrage nicht viele Felder abzufragen und die Prüfsumme sozusagen jedes Mal neu erstellen zu lassen, nein ich brauche dann lediglich ein einziges Feld abzufragen.

                Wenn das in deinen Augen Unsinn ist, sag doch mal warum.

                Was soll die Prüfsumme denn bewirken? Und hast du schon mal was von Indices gehört?

                Was die Prüfsumme bewirken soll steht hier wohl kaum zur Debatte oder ist ist hier neuerdings Pflicht eine Dissertation über die eventuellen Möglichkeiten, einer der Frage betreffenden Zielsetzung, zu schreiben?

                Und was das mit den Indices soll kann ich nicht nachvollziehen. Wenn du damit meinen solltest jedem Feld, was sich in der Prüfsumme wiederspiegelt, einen Index zu verpassen, wäre das eher als SUPERGAU anzusehen und fördert nur meine eigenen Intentionen.

                Jan

                1. Moin!

                  So brauche ich bei einer Abfrage nicht viele Felder abzufragen und die Prüfsumme sozusagen jedes Mal neu erstellen zu lassen, nein ich brauche dann lediglich ein einziges Feld abzufragen.

                  Wenn das in deinen Augen Unsinn ist, sag doch mal warum.

                  Was soll die Prüfsumme denn bewirken? Und hast du schon mal was von Indices gehört?

                  Was die Prüfsumme bewirken soll steht hier wohl kaum zur Debatte oder ist ist hier neuerdings Pflicht eine Dissertation über die eventuellen Möglichkeiten, einer der Frage betreffenden Zielsetzung, zu schreiben?

                  Ich finde, es ist wichtig, dass du den beabsichtigten Zweck der Prüfsumme erklärst. Irgendwie scheint sie ja Teil einer späteren Abfragen werden zu sollen, und sie soll "irgendwas" vereinfachen.

                  Wenn du nicht ins Detail gehen willst: Deine Entscheidung. Dann kann ich dir kaum bessere Alternativen aufzeigen, und du löst dein Problem nicht.

                  Nur soviel: Es ist bei Datenbanken in der Regel NICHT sinnvoll, Daten zu duplizieren, nur um manuell irgendeine bessere Abfragemöglichkeit zu erhalten.

                  Sofern du beabsichtigst, die Prüfsumme für eine eindeutige Identifikation des Datensatzes zu benutzen: Überflüssig, dazu ist ja die ID da.

                  Also: Mehr Details deiner Absichten.

                  - Sven Rautenberg

                  --
                  "Love your nation - respect the others."
                  1. Ich finde, es ist wichtig, dass du den beabsichtigten Zweck der Prüfsumme erklärst. Irgendwie scheint sie ja Teil einer späteren Abfragen werden zu sollen, und sie soll "irgendwas" vereinfachen.

                    »»
                    Es geht hier nicht um ein Problem lediglich um das Wissen einer Möglichkeit. Insofern ist es absolut egal was die Prüfsumme machen soll.
                    Aber das habe ich schon erwähnt:https://forum.selfhtml.org/?t=170241&m=1112635

                    Wenn du nicht ins Detail gehen willst: Deine Entscheidung. Dann kann ich dir kaum bessere Alternativen aufzeigen, und du löst dein Problem nicht.

                    Ich werde das Problem nicht lösen, weil "DU" mir keine Alternative aufzeigst?
                    Diese Ausgae kommentiere ich jetzt lieber mal nicht näher.

                    Nur soviel: Es ist bei Datenbanken in der Regel NICHT sinnvoll, Daten zu duplizieren, nur um manuell irgendeine bessere Abfragemöglichkeit zu erhalten.

                    Sofern du beabsichtigst, die Prüfsumme für eine eindeutige Identifikation des Datensatzes zu benutzen: Überflüssig, dazu ist ja die ID da.

                    Die ID sollte nicht unbedingt öffentlich sein.

                    Na dann schauen wir doch mal was sinnvoller ist:

                    select timex from muell2 where a='xy' and b='xy' and c='xy' and d='xy'...and z='xy';

                    oder

                    select timex from muell2 where passkey='a0e5435jhewe747wkewkuf684kwewuwok';

                    Was glaubst du wohl?

                    Aber um das nochmal zu verdeutlichen, es geht hier nicht um eine Prüfsumme im besonderen, sondern lediglich der effektivste Weg eine noch unbekannte AutoIncrement-ID und/oder andere automatisch generierten Werte ohne gesondert auszulesen im selben Query anzubringen.

                    Und die entscheidenste Frage, dich mich vielleicht weiterbringen könnte ist:

                    insert into muell (abc)values('xyxy');
                    update muell set abc=last_insert_id();
                                             ^^^^^^^   Warum kennt Mysql diesen Wert hier,..

                    insert into muell (abc)values('xyxy');
                    update muell set abc=last_insert_id() where id=last_insert_id();
                                                                       ^^^^^^^^ ... hier aber nicht?

                    Jan

                    1. Yerf!

                      Es geht hier nicht um ein Problem lediglich um das Wissen einer Möglichkeit. Insofern ist es absolut egal was die Prüfsumme machen soll.

                      Dann wisse: es gibt keine Möglichkeit (zumindest nicht ohne größere Umstände). Das was du vorhast wurde so noch von niemanden gebraucht, denn ansonsten gäbe es dazu einen SQL-Befehl...

                      Die ID dient einzig zur Identifizierung eines Datensatzes und sollte sonst keine Information tragen. Weshalb sollte man soetwas an ein anderes Feld anhängen wollen?

                      Na dann schauen wir doch mal was sinnvoller ist:

                      select timex from muell2 where a='xy' and b='xy' and c='xy' and d='xy'...and z='xy';

                      oder

                      select timex from muell2 where passkey='a0e5435jhewe747wkewkuf684kwewuwok';

                      Das hängt ganz vom Anwendungsfall ab: will ich einen Satz aufgrund von 20 Bedingungen finden ist die erste Variante richtig. Will ich aber einen Satz anhand seines Keys finden, so ist es die 2. Variante. Wo ist das Problem?

                      Gruß,

                      Harlequin

                      --
                      <!--[if IE]>This page is best viewed with a webbrowser. Get one today!<![endif]-->
                    2. Moin!

                      Und die entscheidenste Frage, dich mich vielleicht weiterbringen könnte ist:

                      insert into muell (abc)values('xyxy');
                      update muell set abc=last_insert_id();
                                               ^^^^^^^   Warum kennt Mysql diesen Wert hier,..

                      insert into muell (abc)values('xyxy');
                      update muell set abc=last_insert_id() where id=last_insert_id();
                                                                         ^^^^^^^^ ... hier aber nicht?

                      Kann ich dir nicht sagen, weil's bei mir funktioniert.

                      - Sven Rautenberg

                      --
                      "Love your nation - respect the others."