2016-03-23 12 views
1

Ich muss 2 Zeilen in 2 verschiedenen Tabellen aktualisieren und dann eine neue Zeile in eine andere Tabelle einfügen, die ausgeführt werden muss, damit alle erfolgreich sind oder fehlschlagen. (Ich denke, das Wort ist atomar?). Ich habe ein wenig gesucht, kann aber anscheinend nur Fragen finden, die sich auf mehrere Einfügungen oder Aktualisierungen an einer Tabelle beziehen.Mehrere Abfragen ausführen, bei denen alle erfolgreich sind oder alle fehlschlagen

Im Folgenden sind die 3-Abfragen ich ausführen müssen:

UPDATE submission SET status='a' WHERE idgreg = 119 AND status='p' AND userid = 126; 

UPDATE greg SET iscomplete=1 WHERE idgreg = 119; 

INSERT INTO completion (idperson, idgreg, datecompleted, idsubmission, mediaid, description, 
privatestatus, contenttype, totalamount) 
SELECT s.idperson, s.idgreg, s.datesubmitted, s.idsubmission, COALESCE(s.youtubeid, s.contentid) AS mediaidid, g.description, g.privatestatus, 
g.contenttype, COALESCE(SUM(amount),0) AS totalamount 
FROM submission s 
INNER JOIN greg g on s.idgreg = g.idgreg 
INNER JOIN contribution c on s.idgreg = c.idgreg 
WHERE s.idsubmission = 36 AND c.ispaid = 1; 

Antwort

1

Sie Ihre Anfragen, die in einer MySQL Transaktion wickeln sollten um sicherzustellen, dass sie atomar ausgeführt werden. Aber zuerst, Fehler Handler deklarieren, die ROLLBACK alle Änderungen im Falle eines Fehlers:

CREATE PROCEDURE runYourQueries() 

BEGIN 

DECLARE EXIT HANDLER FOR SQLEXCEPTION ROLLBACK; 
DECLARE EXIT HANDLER FOR SQLWARNING ROLLBACK; 

START TRANSACTION; 

UPDATE submission SET status='a' WHERE idgreg = 119 AND status='p' AND userid = 126; 

UPDATE greg SET iscomplete=1 WHERE idgreg = 119; 

INSERT INTO completion (idperson, idgreg, datecompleted, idsubmission, mediaid, description, 
    privatestatus, contenttype, totalamount) 
SELECT s.idperson, s.idgreg, s.datesubmitted, s.idsubmission, 
    COALESCE(s.youtubeid, s.contentid) AS mediaidid, g.description, g.privatestatus, 
    g.contenttype, COALESCE(SUM(amount),0) AS totalamount 
FROM submission s 
INNER JOIN greg g on s.idgreg = g.idgreg 
INNER JOIN contribution c on s.idgreg = c.idgreg 
WHERE s.idsubmission = 36 AND c.ispaid = 1; 

COMMIT; 

END 
+0

Dies hat nicht funktioniert. Ich habe absichtlich einen von ihnen scheitern lassen und die anderen 2 Abfragen noch aktualisiert. Ich habe meiner Hauptfrage ein Bild hinzugefügt, um zu zeigen, was passiert ist. Irgendwelche Ideen? – Mitchell

+0

Sie müssen eine ** transaktionale ** Engine wie * InnoDb * ausgewählt haben. Weitere Informationen finden Sie in der Dokumentation https://dev.mysql.com/doc/refman/5.0/en/ansi-diff-transactions.html –

+0

@Mitchell Sie sollten eine gespeicherte Prozedur verwenden, um "ROLLBACK" zu nutzen, das rückgängig gemacht wird alles im Fehlerfall. –