2009-07-15 11 views
0

Ich versuche zu implementieren "IF Rekord EXISTEN DANN UPDATE ELSE INSERT" in mysql. Insbesondere muss ich herausfinden, wie man das mit Doctrine ORM macht.können Sie eine mysql-Anweisung mit "IF" beginnen?

Eine Lösung, die natives MySql verwendet, ist die Verwendung von "ON DUPLICATE KEY UPDATE". Dies wird in Doctrine leider nicht unterstützt.

Eine andere Semi-Lösung ist die Verwendung der "REPLACE INTO" -Syntax. Doctrine unterstützt dies, REPLACE aktualisiert jedoch keine Datensätze, sondern löscht den Datensatz und erstellt einen neuen (mit einer neuen Autoinkrement-ID). Aus diesem Grund ist es eine schlechte Lösung, wenn Sie wie ich von automatischen Inkrement-IDs abhängig sind .

Die Tabelle, die ich versuchen zu bearbeiten, ist INNODB, also habe ich Transaktionen untersucht, aber ich verstehe nicht völlig, ob die gleichen Regeln innerhalb von Transaktionen gelten, wie sie außerhalb von ihnen gelten.

Kann ich sagen "IF (INSERT IGNORE INTO einfügen critical_id = $ id) DANN ELSE (UPDATE-Tabelle SET field = 'new_value')" innerhalb einer Transaktion verlassen?

Wenn ich so etwas nicht sagen kann, gibt es eine Lösung für dieses Problem?

Antwort

1

entweder einen Weg finden, um „ON DUPLICATE KEY UPDATE“ zu machen die Arbeit, oder wechseln Sie zwei Anweisungen zur Verwendung: zunächst alle vorhandenen Zeilen finden SELECT, dann aktualisieren oder bei Bedarf INSERT.

Das ist so ziemlich Ihre einzige Option, kurz vor dem Erstellen eines gespeicherten Proc, die die oben genannten Arbeit für Sie erledigt.

+0

Ich habe einen Weg gefunden, "ON DUPLICATE KEY" zu verwenden und ich denke, es war die beste Lösung, also werde ich diese Antwort akzeptieren, aber ich versuche immer noch herauszufinden, ob es eine Transaktionslösung ohne mysql-spezifische Terminologie gibt. fwiw, die Frage im Titel wurde nie beantwortet. Ich denke, die Antwort ist, dass Sie eine Anweisung SELECT, INSERT, UPDATE mit IF nicht starten können. Ich habe von einer Eigenschaft namens Recordcount gehört, die in anderen dbms existiert. Ich habe nach einem mysql-Äquivalent gesucht - einem "inner-transactional counter" - um mir mitzuteilen, ob irgendwelche Datensätze geändert wurden. immer noch suchend. – seans

1

"Einfügen oder Aktualisieren" heißt "Upsert". Wenn Sie googlen "upsert mysql" finden Sie, dass es nur wenige Lösungen gibt.

  1. 2-Schritt, Einfügen, dann aktualisieren und Variationen
  2. "ON DUPLICATE KEY UPDATE"
  3. REPLACE

Und vielleicht einige mehr, aber die meisten von ihnen sind Variationen.

Transaktionen verwenden Ihre SQL würde wie folgt aussehen:

UPDATE xxx SET (x1, x2) = (y1, y2) WHERE id = myid; 
    IF found THEN 
     RETURN; 
    END IF; 
    BEGIN 
     INSERT INTO xxx (x1, x2) VALUES (y1, y2); 
     RETURN; 
    EXCEPTION WHEN unique_violation THEN 
    --##Do nothing, or you can put this whole sql code 
    --##in a LOOP and it will loop over and try update again 
    END; 

Dieser Code ist von einer meiner postgresql Funktionen beraubt. Ich denke, InnoDB unterstützt das nicht, aber ich könnte falsch liegen.