it-swarm.com.de

Wie teste ich eine SQL Update-Anweisung, bevor Sie sie ausführen?

In einigen Fällen kann die Ausführung einer UPDATE-Anweisung in der Produktion den Tag retten. Ein verzerrtes Update kann jedoch schlimmer sein als das ursprüngliche Problem.

Welche Optionen gibt es nicht, wenn eine Testdatenbank verwendet wird, um festzustellen, was eine Aktualisierungsanweisung macht, bevor sie ausgeführt wird?

69
static_rtti

Neben der Verwendung einer Transaktion, wie von Imad bereits erwähnt (sollte ohnehin obligatorisch sein), können Sie auch eine Überprüfung der Systemintegrität durchführen, indem Sie select mit derselben WHERE-Klausel wie UPDATE ausführen.

Also wenn du UPDATE bist 

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

Nachfolgend sehen Sie, welche Zeilen aktualisiert werden:

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

Autocommit AUS ...

MySQL

set autocommit=0;

Damit wird die automatische Übergabe für die aktuelle Sitzung deaktiviert.

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

BEARBEITEN: Die Verwendung von Transaktionen anstelle der Ausführung einer Auswahlabfrage hat den Vorteil, dass Sie die Ergebnismenge einfacher überprüfen können.

48
Imad Moqaddem

Was ist mit Transaktionen? Sie haben das ROLLBACK-Feature.

@see https://dev.mysql.com/doc/refman/5.0/de/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 die Frage von @rickozoe unten:

Im Allgemeinen werden diese Zeilen nicht einmal ausgeführt. In PHP f.e. du würdest sowas schreiben (vielleicht ein bisschen sauberer, wollte aber schnell antworten ;-)):

$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 die Verwendung von MySQL-Variablen (siehe https://dev.mysql.com/doc/refman/5.7/en/user-variables.htm l Und https : //stackoverflow.com/a/18499823/1416909 ):

# 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;

Ich würde jedoch vorschlagen, die Sprachumhüllungen zu verwenden, die in Ihrer bevorzugten Programmiersprache verfügbar sind.

46
Marcel Lange

Ich weiß, dass dies eine Wiederholung anderer Antworten ist, aber es hat einige emotionale Unterstützung, um den zusätzlichen Schritt für das Testen des Updates zu unternehmen: D

Zum Testen des Updates ist Hash # Ihr Freund.

Wenn Sie eine Aktualisierungsanweisung haben, wie:

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

Du gehst UPDATE und SET zum Testen raus und hieb sie dann wieder an:

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

Es funktioniert für einfache Aussagen.

Eine zusätzliche, praktisch obligatorische Lösung ist, eine Kopie (Backup-Duplikat) zu erhalten, wenn ein Update für eine Produktionstabelle verwendet wird. Phpmyadmin> Vorgänge> Kopie: table_yearmonthday. Bei Tischen <= 100M dauert es nur wenige Sekunden.

9
Johan

Keine direkte Antwort, aber ich habe schon viele falsche Daten-Situationen gesehen, die man hätte vermeiden können, wenn die Klausel WHERE zuerst eingetippt! Manchmal hilft ein WHERE 1 = 0 dabei, eine Arbeitsanweisung auch sicher zusammenzustellen. Ein Blick auf einen geschätzten Ausführungsplan, der die betroffenen Zeilen abschätzt, kann hilfreich sein. Darüber hinaus in einer Transaktion, die Sie zurücksetzen, wie andere gesagt haben.

4
David M

Führen Sie die Auswahlabfrage für dieselbe Tabelle mit allen where-Bedingungen aus, die Sie in der Aktualisierungsabfrage anwenden.

1
manurajhada

mache eine SELECT davon,

wie wenn du gekommen bist

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

konvertiere es in

SELECT * FROM users WHERE name='jan'

0
EaterOfCode

In diesen Fällen, die Sie testen möchten, ist es ratsam, sich nur auf die Werte der aktuellen Spalten und der bald zu aktualisierenden Spaltenwerte zu konzentrieren.

Bitte schauen Sie sich den folgenden Code an, den ich geschrieben habe, um die WHMCS-Preise zu aktualisieren:

# UPDATE tblinvoiceitems AS ii

SELECT                        ###  JUST
    ii.amount AS old_value,   ###  FOR
    h.amount AS new_value     ###  TESTING
FROM tblinvoiceitems AS ii    ###  PURPOSES.

JOIN tblhosting AS h ON ii.relid = h.id
JOIN tblinvoices AS i ON ii.invoiceid = i.id

WHERE ii.amount <> h.amount   ### Show only updatable rows

# SET ii.amount = h.amount

Auf diese Weise vergleichen wir bereits vorhandene Werte mit neuen Werten.

0
Mohammad Naji