2012-06-13 6 views
55

In einigen Fällen kann das Ausführen einer UPDATE-Anweisung in der Produktion den Tag speichern. Ein borked Update kann jedoch schlechter sein als das ursprüngliche Problem.Wie testen Sie eine SQL Update-Anweisung vor dem Ausführen?

Kurz vor der Verwendung einer Testdatenbank, welche Möglichkeiten gibt es zu sagen, was eine Update-Anweisung tun wird, bevor sie ausgeführt wird?

Antwort

24

Zusätzlich zur Verwendung einer Transaktion, wie Imad gesagt hat (die ohnehin obligatorisch sein sollte), können Sie auch eine Plausibilitätsprüfung durchführen, welche Zeilen betroffen sind, indem ein select mit derselben WHERE-Klausel wie das UPDATE ausgeführt wird.

Also, wenn Sie UPDATE ist

UPDATE foo 
    SET bar = 42 
WHERE col1 = 1 
    AND col2 = 'foobar'; 

Im Folgenden wird Ihnen zeigen, welche Zeilen aktualisiert werden:

SELECT * 
FROM foo 
WHERE col1 = 1 
    AND col2 = 'foobar'; 
+1

Die Verwendung von Transaktionen ist besser, um die Daten dann zu überprüfen. Angenommen, er möchte das Ergebnis überprüfen, schließe ich seine Aussage ist komplexer als ein 'SET-Balken = 42', so dass er in seiner Sitzung mehrere Abfragen machen kann, um die resultierende Menge von Daten zu testen ... –

+1

@ImadMoqaddem: Ich stimme zu und deshalb schrieb ich "* Abgesehen von der Verwendung einer Transaktion, wie Imad sagte *" –

+0

Und wenn Sie 'Fremdschlüssel UPDATE CASCADE' Ihre SQL-Fehler – Green

40

Autocommit OFF ...

MySQL

set autocommit=0; 

Es setzt den autommit für die aktuelle Sitzung.

Sie führen Ihre Anweisung aus, sehen, was sie geändert hat, und führen dann ein Rollback durch, wenn es falsch ist, oder commit, wenn es das ist, was Sie erwartet haben!

BEARBEITEN: Der Vorteil der Verwendung von Transaktionen anstelle von Select-Abfrage ist, dass Sie die resultierende Menge einfacher überprüfen können.

+7

Überprüfen Sie einfach Ihre Tabelle unterstützt Transaktionen ... –

+4

@dystroy: jedes sinnvolle DBMS unterstützt Transaktionen. –

+3

Denken Sie nur daran, die Transaktion schnell zu bestätigen oder rückgängig zu machen, sonst riskieren Sie, andere Transaktionen zu blockieren - und bringen Ihre Anwendung im schlimmsten Fall zum Erliegen. Keine gute Idee, die Abfrage auszuführen, dann zu Mittag essen und dann zurückkommen, um die Ergebnisse zu sehen! :-) –

1

Führen Sie in derselben Tabelle eine Abfrage mit allen where Bedingungen aus, die Sie in der Aktualisierungsabfrage anwenden.

0

eine SELECT davon machen,

wie wenn Sie bekam

UPDATE users SET id=0 WHERE name='jan'

wandeln es in

SELECT * FROM users WHERE name='jan'

3

keine direkte Antwort, aber ich habe viele borked prod Daten Situationen gesehen, die von Eingabe des WHERE Klausel erste hätte vermieden werden können! Manchmal kann auch eine WHERE 1 = 0 helfen, eine Arbeitsanweisung sicher zusammenzustellen. Es kann nützlich sein, einen geschätzten Ausführungsplan zu betrachten, der die betroffenen Zeilen schätzt. Darüber hinaus, in einer Transaktion, die Sie zurückrollen, wie andere gesagt haben.

+1

Was ist los mit 'WHERE FALSE'? – SystemParadox

+0

@SystemParadox - nichts, obwohl 'WHERE 1 = 0' tragbarer ist, wenn jemand darüber stolpert, der mit einem anderen DBMS arbeitet. Beispielsweise akzeptiert SQL Server "WHERE FALSE" nicht. –

6

Ich weiß, das eine Wiederholung von anderen Antworten, aber es hat einige emotionale Unterstützung den zusätzlichen Schritt zum Testen Update zu nehmen: D

Zum Testen Update Hash # ist dein Freund.

Wenn Sie eine Update-Anweisung haben, wie:

UPDATE 
wp_history 
SET history_by="admin" 
WHERE 
history_ip LIKE '123%' 

Sie Hash-UPDATE und zum Testen von SET, dann sie hash zurück in:

SELECT * FROM 
#UPDATE 
wp_history 
#SET history_by="admin" 
WHERE 
history_ip LIKE '123%' 

Es ist für einfache Aussagen funktioniert.

Eine weitere praktisch obligatorische Lösung ist, eine Kopie (Backup-Duplikat) zu erhalten, wenn Sie das Update auf einer Produktionstabelle verwenden. Phpmyadmin> operations> Kopieren: table_yearmonthday. Es dauert nur ein paar Sekunden für die Tabellen < = 100M.

33

Was ist mit Transaktionen? Sie haben die ROLLBACK-Funktion.

@see https://dev.mysql.com/doc/refman/5.0/en/commit.html

Zum Beispiel:

START TRANSACTION; 
SELECT * FROM nicetable WHERE somthing=1; 
UPDATE nicetable SET nicefield='VALUE' WHERE somthing=1; 
SELECT * FROM nicetable WHERE somthing=1; #check 

COMMIT; 
# or if you want to reset changes 
ROLLBACK; 

SELECT * FROM nicetable WHERE somthing=1; #should be the old value 

Antwort auf Frage von @rickozoe unter:

In der Regel sind diese Linien nicht als einmal ausgeführt werden. In PHP f.

$MysqlConnection->query('START TRANSACTION;'); 
$erg = $MysqlConnection->query('UPDATE MyGuests SET lastname='Doe' WHERE id=2;'); 
if($erg) 
    $MysqlConnection->query('COMMIT;'); 
else 
    $MysqlConnection->query('ROLLBACK;'); 

Eine andere Möglichkeit wäre MySQL Variablen zu verwenden (siehe https://dev.mysql.com/doc/refman/5.7/en/user-variables.htm l und https://stackoverflow.com/a/18499823/1416909 ): Sie würde so etwas (vielleicht ein wenig sauberer, aber wollte antworten schnell ;-)) schreiben

# do some stuff that should be conditionally rollbacked later on 

SET @v1 := UPDATE MyGuests SET lastname='Doe' WHERE id=2; 
IF(v1 < 1) THEN 
    ROLLBACK; 
ELSE 
    COMMIT; 
END IF; 

Aber ich würde vorschlagen, die Sprache Wrapper in Ihrer bevorzugten Programmiersprache zu verwenden.

+0

Schöne sichere Annäherung, danke. – input

+0

Dies wird unerwartete Ergebnisse mit verschachtelten Transaktionen haben. – scones

+0

Können Sie bitte ein Beispiel geben? –