115

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

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

4

9 に答える 9

103

トランザクションはどうですか?彼らはロールバック機能を持っています。

@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 feでは、次のようなものを記述します(おそらく少しクリーンですが、すばやく答えたいと思います;-)):

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

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

于 2015-07-15T21:46:47.430 に答える
65

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

だからあなたが更新するなら

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

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

SELECT *
FROM foo
WHERE col1 = 1
  AND col2 = 'foobar';
于 2012-06-13T08:59:26.103 に答える
62

自動コミットオフ..。

MySQL

set autocommit=0;

現在のセッションの自動コミットをオフに設定します。

ステートメントを実行し、何が変更されたかを確認してから、間違っている場合はロールバックするか、期待どおりの場合はコミットします。

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

于 2012-06-13T08:57:28.017 に答える
11

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

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

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

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

UPDATEとSETをハッシュしてテストし、ハッシュして次の場所に戻します。

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

単純なステートメントで機能します。

追加の実質的に必須の解決策は、本番テーブルで更新を使用するときはいつでも、コピー(バックアップの複製)を取得することです。Phpmyadmin>操作>コピー:table_yearmonthday。テーブルが1億未満の場合は数秒かかります。

于 2013-02-26T13:51:01.277 に答える
6

直接的な答えではありませんが、最初に句を入力するWHEREことで回避できた可能性のある、多くの中断された製品データの状況を見てきました。場合によってはWHERE 1 = 0、作業ステートメントを安全にまとめるのにも役立ちます。また、影響を受ける行を推定する推定実行プランを確認すると役立つ場合があります。それを超えて、他の人が言ったようにあなたがロールバックするトランザクションで。

于 2012-06-13T09:08:23.973 に答える
4

それを作るSELECT

あなたが得た場合のように

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

に変換する

SELECT * FROM users WHERE name='jan'

于 2012-06-13T09:00:14.387 に答える
4

もう1つのオプションは、MySQLにクエリプランを要求することです。これは2つのことを教えてくれます:

  • クエリに構文エラーがあるかどうか、ある場合は、クエリプランコマンド自体が失敗します
  • MySQLがクエリの実行をどのように計画しているか、たとえば、どのインデックスを使用するか

MySQLおよびほとんどのSQLデータベースでは、クエリプランコマンドはdescribeですので、次のようにします。

describe update ...;
于 2020-10-17T23:26:32.267 に答える
3

テストする場合は、現在の列の値と間もなく更新される列の値のみに焦点を当てることをお勧めします。

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

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

于 2018-10-13T18:01:20.500 に答える
1

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

于 2012-06-13T08:59:18.250 に答える