Martin Fleck: Bei 'duplicate key' zusätzlichen Query ausführen?

hallo,

ich habe eine einfache Tabelle mit den Feldern "id" (auto_increment) und "data" (unique). Nach dem Einfügen des Datensatzes benötige ich die "id", um eine Relation zu einem anderen Datensatz in einer neuen Tabelle erstellen zu können.

Wenn ich versuche einen bereits vorhandenen Eintrag nochmal reinzuschreiben, bekomme ich die Meldung "duplicate key". Soweit ist das ja auch gut. Aber muss ich dann zusätzlich ein SQL-Query (select id from table where data = 'test') machen um die ID des bereits bestehenden Datensatzes auszulesen? Ich finde das sehr umständlich und unsauber.

Vielen Dank.

--
Martin Fleck

  1. Hallo,

    ich habe eine einfache Tabelle mit den Feldern "id" (auto_increment) und "data" (unique).

    Was ist der primary key?

    Wenn ich versuche einen bereits vorhandenen Eintrag nochmal reinzuschreiben,

    mit was fuer einer Query?

    bekomme ich die Meldung "duplicate key". Soweit ist das ja auch gut.

    OK, Du bist also froh, dass Du nicht drueberschreiben kannst.

    Sonst haette ich Dir REPLACE anstatt INSERT empfohlen.
    http://www.mysql.com/doc/de/REPLACE.html

    Sorry, die eigentliche Frage kann ich nicht beantworten.

    Gruesse,

    Thomas

    1. Was ist der primary key?

      Das Feld "id" ist der Primary Key.

      mit was fuer einer Query?

      insert into test_table (data) values ('test');

      --
      Martin Fleck

  2. Hi,

    Wenn ich versuche einen bereits vorhandenen Eintrag nochmal reinzuschreiben, bekomme ich die Meldung "duplicate key". Soweit ist das ja auch gut. Aber muss ich dann zusätzlich ein SQL-Query (select id from table where data = 'test') machen um die ID des bereits bestehenden Datensatzes auszulesen? Ich finde das sehr umständlich und unsauber.

    Du willst ein "UPDATE" machen, wenn der Datensatz (in seiner Eindeutigkeit ;-) schon da ist und ein "INSERT", wenn der noch nicht da ist?

    Und Du wunderst Dich, dass dieser, asu Deiner Sicht natuerliche Gebrauchsfall nicht adaequat unterstuetzt wird?

    Gruss,
    Lude

    1. Du willst ein "UPDATE" machen, wenn der Datensatz (in seiner Eindeutigkeit ;-) schon da ist und ein "INSERT", wenn der noch nicht da ist?

      Nein. Wenn der entsprechende Datensatz vorhanden ist, benötige ich die ID (dies mache ich bisher mit einem zusätzlichen SQL-Query). Ist noch kein Datensatz vorhanden, dann wird dieser mit insert erzeugt.

      --
      Martin Fleck

      1. Hi,

        Nein. Wenn der entsprechende Datensatz vorhanden ist, benötige ich die ID (dies mache ich bisher mit einem zusätzlichen SQL-Query). Ist noch kein Datensatz vorhanden, dann wird dieser mit insert erzeugt.

        prima. Aber was erwartest Du da vom RDBMS? Die o.g. Logik musst Du selbst formulieren und vorzugsweise dort (als Stored Procedure?) bzw. im "Datenclient-Code" ablegen.

        Gruss,
        Lude

        1. prima. Aber was erwartest Du da vom RDBMS?

          Ok, dann weiß ich jetzt bescheid. Dieser Prozess wird so oft benötigt, daher dachte ich das es auch einfacher gehen muss.

          Die o.g. Logik musst Du selbst formulieren und vorzugsweise dort (als Stored Procedure?) bzw. im "Datenclient-Code" ablegen.

          Hast du da nähere Informationen dazu? Meinst du damit Funktionen in eine Datenbank ablegen und diese dann mit select function() aufzurufen?

          --
          Martin Fleck

          1. Hi,

            Die o.g. Logik musst Du selbst formulieren und vorzugsweise dort (als Stored Procedure?) bzw. im "Datenclient-Code" ablegen.

            Hast du da nähere Informationen dazu? Meinst du damit Funktionen in eine Datenbank ablegen und diese dann mit select function() aufzurufen?

            ich kenne nur den 'MS SQL Server' seit Version '6.5'. Dieser Server stellt als Datenbankobjekt sog. Stored Procedures bereit, die serverseitig gespeichert und kompiliert werden.

            Fuer "Insert-Zwecke" gibt's dann in der Regel eine Prozedur mit dem Namen 'SET_<TABELLENNAME_IM_SINGULAR>' fuer "Update-Zwecke" ein 'LET_<TABELLENNAME_IM_SINGULAR>'. - Ich tendiere dazu zwischen den CRUDL-Zugriffen sauber zu unterscheiden. Ein "Insdate" als Stored Procedure gefaellt mir irgendwie nicht, aber OK...

            Datenclientseitiges Zusammenbasteln von SQL-Statements halte ich fuer problematisch, denn dann geht die Skalierbarkeit des Systems vor die Hunde.

            Gruss,
            Lude

      2. Hello,

        Du willst ein "UPDATE" machen, wenn der Datensatz (in seiner Eindeutigkeit ;-) schon da ist und ein "INSERT", wenn der noch nicht da ist?

        Nein. Wenn der entsprechende Datensatz vorhanden ist, benötige ich die ID (dies mache ich bisher mit einem zusätzlichen SQL-Query). Ist noch kein Datensatz vorhanden, dann wird dieser mit insert erzeugt.

        Und wenn Du was mit der Information anfangen willst, dann müsstest Du den Satz für die Dauer der folgenden Bearbeitung ggf. schreibschützen (writelock).

        Grüße

        Tom

  3. Moin!

    ich habe eine einfache Tabelle mit den Feldern "id" (auto_increment) und "data" (unique). Nach dem Einfügen des Datensatzes benötige ich die "id", um eine Relation zu einem anderen Datensatz in einer neuen Tabelle erstellen zu können.

    MySQL? Dann beschäftige dich mit der MySQL-Funktion LAST_INSERT_ID(), bzw. mit der Funktion mysql_insert_id() deiner MySQL-API. PHP hat die gleichlautende Funktion beispielsweise implementiert.

    - Sven Rautenberg

    --
    "Beim Stuff für's Web gibts kein Material, was sonst das Zeugs ist, aus dem die Sachen sind."
    (fastix®, 13. Oktober 2003, 02:26 Uhr -> </archiv/2003/10/60137/#m338340>)
    1. MySQL? Dann beschäftige dich mit der MySQL-Funktion LAST_INSERT_ID(), bzw. mit der Funktion mysql_insert_id() deiner MySQL-API. PHP hat die gleichlautende Funktion beispielsweise implementiert.

      Nein, Postgresql. Die Funktion "mysql_insert_id" ist mir bekannt, das hilft aber nichts wenn die Meldung "duplicate key" kommt oder bekomme ich dort etwa die id des ersten Datensatz zurück?

      --
      Martin Fleck

      1. Hello,

        Nein, Postgresql. Die Funktion "mysql_insert_id" ist mir bekannt, das hilft aber nichts wenn die Meldung "duplicate key" kommt oder bekomme ich dort etwa die id des ersten Datensatz zurück?

        willst Du den ersten Satz überschreiben? Dann bietet MxSQL die Möglichkeit mit REPLACE. Funktioniert wie eine Mischung aus INSERT und UPDATE. Da gibt's bestimmt auch was von Bosch *äh* PostgreSQL wollte ich sagen.

        Und sonst kann man noch Options setzen bei Insert. Kommt dann aufs gleiche raus...

        Tom

        1. willst Du den ersten Satz überschreiben?

          Eigentlich nicht. Aber was ist denn schneller?

          Möglichkeit 1:
          Replace und ein select-Query um die "id" auszulesen.

          Möglichkeit 2:
          Wert mit insert schreiben. Wenn dann ein Fehler (duplicate key) auftaucht, zusätzlich mit einer select-Query die "id" auslesen.

          Möglichkeit 3:
          Erst ein select-Query und wenn die "id" null ist, dann den Wert mit insert schreiben.

          Ich finde alle Möglichkeiten nicht sauber. Gibt es noch andere?

          Dann bietet MxSQL die Möglichkeit mit REPLACE. Funktioniert wie eine Mischung aus INSERT und UPDATE.

          Ja, aber ich komme dann in einem Rutsch nicht an die "id" heran, oder?

          --
          Martin Fleck

    2. Hello,

      MySQL? Dann beschäftige dich mit der MySQL-Funktion LAST_INSERT_ID(), bzw. mit der Funktion mysql_insert_id() deiner MySQL-API. PHP hat die gleichlautende Funktion beispielsweise implementiert.

      Die aber nur für kurze Schlüssel funktioniert.
      Bei Tabellen mit vielen Datensätzen oder viel Bewegung (also hohen Schlüsselnummern) sollte man lieber das SQL-Statement benutzen.

      Aber Du hast ja leider PostgreSQL, da kenn ich mich nicht aus.

      Grüße

      Tom

  4. Hi,

    ich habe eine einfache Tabelle mit den Feldern "id" (auto_increment) und "data" (unique). Nach dem Einfügen des Datensatzes benötige ich die "id", um eine Relation zu einem anderen Datensatz in einer neuen Tabelle erstellen zu können.

    'MS SQL Sever'? Dann gaebe es die Systemvariable '@@identity', die man abfragen kann.

    Gruss,
    Lude

    1. 'MS SQL Sever'? Dann gaebe es die Systemvariable '@@identity', die man abfragen kann.

      Nein, Postgresql. Vielleicht gibt es dort ja etwas vergleichbares?

      --
      Martin Fleck