Lukas.: ON DUPLICATE KEY UPDATE

Hi,

was muß ich tun, damit ich über

insert into tabelle (ID,K_ID,V_ID,...) VALUES ($id,$k_id,$v_id...) ON DUPLICATE KEY UPDATE ...

ein Update anstelle eines Insert erreiche und zwar genau dann, wenn:

  • die Kombination aus V_ID und K_ID nicht mehr "unique" wäre.

Ich kenne leider die Vorgehensweise nicht, d.h. wie mache ich das meiner mysql-db klar und wie muß die Query hierzu ausschauen?

Lukas

  1. Tach!

    was muß ich tun, damit ich über [...] ein Update anstelle eines Insert erreiche und zwar genau dann, wenn:

    • die Kombination aus V_ID und K_ID nicht mehr "unique" wäre.

    Als erstes brauchst du einen Unique-Index über beide Spalten. Ein Index über beide Spalten, nicht zwei Indexe jeweils über je eine Spalte. Und der Rest geht so, wie die Syntax im Handbuch beschrieben ist.

    dedlfix.

    1. Hi,

      Als erstes brauchst du einen Unique-Index über beide Spalten. Ein Index über beide Spalten, nicht zwei Indexe jeweils über je eine Spalte.

      Habe ich so gemacht: ... UNIQUE KEY K_ID_2 (K_ID,V_ID), KEY K_ID (K_ID), ...

      Das K_ID_2 war nicht meine Idee, das hat phpmyadmin selber so gemacht, vermutlich weil es KEY K_ID (K_ID) bereits gab?

      Und der Rest geht so, [wie die Syntax im Handbuch beschrieben ist

      ON DUPLICATE KEY UPDATE K_ID=K_ID

      scheint zu machen, was ich vorhabe. Kannst Du mir sagen, warum?

      Lukas

      1. Moin!

        ON DUPLICATE KEY UPDATE K_ID=K_ID

        scheint zu machen, was ich vorhabe.

        scheint

        Kannst Du mir sagen, warum?

        Weil es nichts tut. Das hier tut was:

        CREATE TABLE `test` (
        `id_a` int( 11 ) NOT NULL ,
        `id_b` int( 11 ) NOT NULL ,
        `data_a` text( 11 ) NOT NULL ,
        `data_b` text( 11 ) NOT NULL
        ) ENGINE = InnoDB DEFAULT CHARSET = utf8;
        
        ALTER TABLE `test` ADD UNIQUE (
        `id_a` ,
        `id_b`
        );
        
        INSERT INTO `test` ( `id_a` , `id_b` , `data_a` , `data_b` ) VALUES (
        '1', '1', 'foo', 'bar'
        );
        
        INSERT INTO `test` ( `id_a` , `id_b` , `data_a` , `data_b` ) VALUES (
        '1', '1', 'baz', 'toc'
        ) ON DUPLICATE KEY UPDATE 
        `data_a` = 'baz',
        `data_b` = 'toc';
        

        Jörg Reinholz

  2. Moin!

    Hi,

    was muß ich tun, damit ich über

    insert into tabelle (ID,K_ID,V_ID,...) VALUES ($id,$k_id,$v_id...) ON DUPLICATE KEY UPDATE ...
    

    Ich ergänze das mal:

    INSERT INTO TABELLE (ID,K_ID,V_ID, FOO, BAZ) VALUES ($id,$k_id,$v_id, 'bar', 'toc') ON DUPLICATE KEY UPDATE FOO='bar', BAZ='toc';
    

    Zuvor natürlich die Tabelle so einrichten, dass es den Unique-Index für K_ID,V_ID überhaupt gibt.

    Jörg Reinholz

  3. Liebe Mitdenker, liebe Wissende, liebe Neugierige,

    was muß ich tun, damit ich über

    insert into tabelle (ID,K_ID,V_ID,...) VALUES ($id,$k_id,$v_id...) ON DUPLICATE KEY UPDATE ...
    

    ein Update anstelle eines Insert erreiche und zwar genau dann, wenn:

    • die Kombination aus V_ID und K_ID nicht mehr "unique" wäre.

    Du vermischst da zwei Standard-Trigger/Constraints von MySQL miteinander.

    Wenn Du möchtest, dass ein Insert nur funktioniert, wenn ein bestimmter Key noch nicht existiert, muss der zuerst einmal angelegt sein als Unique Key (also über alle betroffenen Spalten).

    Und dann führst Du das Insert einfach durch. Wenn der Unique Key über die betroffenen Spalten bereits existiert hat, wird das Insert abgelehnt und eine entsprechende MySQL-Error-Message steht zur Verfügung.

    Wenn Dein Ansinnen aber nur zeilenweise vorkommen sollte (also nicht generell für die Tabelle gilt), dann hilft Dir eine stored Routine, die per Funktionsargument die passende Anweisung entgegen nimmt.

    Spirituelle Grüße
    Euer Robert
    robert.r@online.de

    --
    Möge der wahre Forumsgeist ewig leben!
    1. Hallo robertroth,

      Du vermischst da zwei Standard-Trigger/Constraints von MySQL miteinander.

      Nein. UPSERT existiert.

      LG,
      CK

      1. Lieber Christian, liebe Mitdenker, liebe Wissende, liebe Neugierige,

        Du vermischst da zwei Standard-Trigger/Constraints von MySQL miteinander.

        Nein. UPSERT existiert.

        Sorry, ich war über die Formulierung gestolpert und die irgendwie in einem anderen Quadranten verortet, als sie wohl lag...

        Also:

        Update, wenn der Konbinationsschlüssel nicht unique ist == Update, wenn der Kombinationsschlüssel duplicate ist

        Und da hast Du selbstverständlich Recht, das gibt's tatsächlich schon - von MySQL :-)
        Man muss eben nur einen eineindeutigen Kombinationsschlüssel dafür anlegen, dann wird er auch berücksichtigt.

        Spirituelle Grüße
        Euer Robert
        robert.r@online.de

        --
        Möge der wahre Forumsgeist ewig leben!