web-dev-qa-db-ja.com

SQL Updateステートメントを実行する前にテストする方法は?

場合によっては、実稼働環境でUPDATEステートメントを実行すると、1日を節約できます。ただし、更新の中断は、最初の問題よりも悪化する可能性があります。

テストデータベースを使用する以外に、実行前に更新ステートメントが何をするかを伝えるオプションは何ですか?

77
static_rtti

Imadが言ったようにトランザクションを使用することに加えて(これは必須です)、UPDATEと同じWHERE句を使用してselectを実行することにより、影響を受ける行の健全性チェックを行うこともできます。

更新する場合は

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

以下は、更新される行を示します。

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

トランザクションはどうですか? ROLLBACK機能があります。

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

例えば:

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

以下の@rickozoeからの質問に答えてください:

一般に、これらの行は一度だけ実行されません。 PHP f.e.あなたはそのような何かを書くでしょう(おそらく少しきれいですが、すぐに答えたいと思いました;-)):

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

別の方法は、MySQL変数を使用することです( https://dev.mysql.com/doc/refman/5.7/en/user-variables.htm lおよび 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;

ただし、お気に入りのプログラミング言語で使用可能な言語ラッパーを使用することをお勧めします。

57
Marcel Lange

自動コミットオフ...

MySQL

set autocommit=0;

現在のセッションの自動調整をオフにします。

ステートメントを実行し、変更内容を確認し、間違っている場合はロールバックするか、期待したとおりであればコミットします!

編集:選択クエリを実行する代わりにトランザクションを使用する利点は、結果セットを簡単に確認できることです。

51
Imad Moqaddem

私はこれが他の答えの繰り返しであることを知っていますが、アップデートをテストするための追加のステップを取るためのいくつかの感情的なサポートがあります:D

更新のテストでは、ハッシュ#があなたの友達です。

次のような更新ステートメントがある場合:

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

UPDATEをハッシュしてテスト用に設定し、次にそれらを再度ハッシュします。

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

単純なステートメントに対して機能します。

実質的に必須の追加ソリューションは、実動テーブルで更新を使用するたびにコピー(バックアップ複製)を取得することです。 Phpmyadmin>操作>コピー:table_yearmonthday。テーブルが1億以下の場合、数秒かかります。

11
Johan

直接的な答えではありませんが、最初にWHERE句を入力する!時々、WHERE 1 = 0は、作業文を安全にまとめるのにも役立ちます。また、影響を受ける行を推定する推定実行計画を確認すると役立ちます。それを超えて、他の人が言ったようにロールバックするトランザクションで。

4
David M

更新クエリで適用するすべてのwhere条件を使用して、同じテーブルで選択クエリを実行します。

1
manurajhada

SELECTを作成し、

もしもらったら

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

に変換する

SELECT * FROM users WHERE name='jan'

0
EaterOfCode

これらのケースでテストしたい場合は、current列の値とsoon-to-be-bed-updated列の値のみに注目することをお勧めします。

WHMCS価格を更新するために書いた次のコードを見てください。

# 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

このようにして、既存の値と新しい値を明確に比較します。

0
Mohammad Naji