
本番データをSQLで直すときの安全手順|バックアップと件数確認
「お客さまのこのデータ、間違ってるからSQLで直しておいて」。 そう頼まれて本番のDBに向かうとき、軽い作業のはずなのに、なぜか手が震えますよね。
UPDATE の WHERE を1つ書き忘れただけで、全件が同じ値に書き換わる。 DELETE の条件をミスすれば、消してはいけない行まで消える。 しかも本番は、画面の操作と違って「ひとつ前に戻る」ボタンがありません。
一人で保守運用をしていると、このデータ修正を相談する相手もいないまま、自分一人で実行ボタンを押すことになります。 だからこそ、度胸ではなく手順で守るのがいちばん安全です。この記事では、本番データをSQLで直すときに、事故を防ぎながら進める順番を一緒に整理します。考えなくても手が止まる仕組みを、先に作っておきましょう。
結論:本番データをSQLで直すときは、①バックアップを取る → ②SELECTで対象と件数を先に確認 → ③トランザクションで囲む → ④UPDATE/DELETEを実行して影響件数を照合 → ⑤件数が想定どおりならCOMMIT、違えばROLLBACKの順で進めます。いきなりUPDATEを打たず、「同じWHEREで先にSELECT COUNT(*)」を挟むだけで、事故の大半は防げます。
DBの種類(MySQL・PostgreSQL・その他)や権限、本番の運用ルールによって、できることは変わります。 この記事の手順は出発点として、自分の現場のルールと環境に置き換えて使ってください。会社で「本番への直接SQLは申請が必要」と決まっているなら、まずそのルールが最優先です。
なぜ本番のデータ修正は怖いのか
データ修正が画面操作より怖いのは、理由があります。ここを言葉にしておくと、手順の一つひとつが「なぜ必要か」で腑に落ちます。
- 取り消しが効かない:
UPDATEやDELETEは、コミットした瞬間に元の値が上書き・消去されます。アプリの「キャンセル」とは違います。 - 影響範囲が見えにくい:1行直すつもりが、
WHEREの条件次第で何百行にも届きます。実行するまで、何行に当たるか目で見えません。 - 連動する処理がある:そのデータを使う集計・バッチ・通知が裏で動いていることがあります。値を変えると、後続の出口(帳票・メール)にも波及します。
つまり怖いのは、あなたの腕のせいではなく、「見えないまま、戻せない操作をする」という構造のせいです。 だったら、見えるようにして、戻せるようにすればいい。それが次の手順です。
安全に直す5つの手順(順番に)

頼まれたデータ修正は、次の順番で進めます。 各ステップは「戻せる状態」と「見える状態」を先に作るためのものです。焦っているときほど、上から順に。
① まずバックアップ(控え)を取る
実行の前に、戻せる準備をします。これがあるだけで、心の余裕がまったく変わります。
- 範囲が広い・重要な作業なら、テーブルのダンプを取る(例:
mysqldumpで対象テーブルだけ書き出す)。 - 小さな修正でも、直す行を別テーブルに退避しておくと安心です。
例:CREATE TABLE backup_orders_0625 AS SELECT * FROM orders WHERE id IN (...);
- 権限や容量でダンプ・退避が取れない現場も多いです。
CREATE権限がない、空き容量がない、重くて打てない——そんなときは、直す前の値をSELECTしてCSV・テキストに残すだけでも控えになります。あとで手で戻せるので、これを本線の代わりとして使って大丈夫です。
退避テーブルやダンプが取れるならそれがベスト、取れないなら値をテキストに残す。どちらでもいいので、「戻せる控えがどこにあるか」を一言で言える状態にしてから、次へ進みます。
② 同じWHEREで、先にSELECTして件数を見る
ここが、この記事でいちばん伝えたい一手です。UPDATEやDELETEを打つ前に、まったく同じWHEREでSELECTする。
- 件数を見る:
SELECT COUNT(*) FROM orders WHERE status = 'pending' AND user_id = 123; - 中身を見る:
SELECT * FROM orders WHERE status = 'pending' AND user_id = 123;
ここで出た件数が「直したい行数」と一致しているかを確かめます。 「1件直すはずが、COUNTが400件」なら、そのWHEREはどこかが緩すぎます。実行する前に気づけました。逆に0件なら、条件が厳しすぎるか、対象が違います。
この「先にSELECT」を挟むだけで、WHEREの書き間違いの大半は実行前に止められます。
なお、SETで書き換える列を、そのままWHEREの条件にも使う修正(例:status='pending'の行をstatus='done'に変える)では、実行後にWHERE条件に当たる行が変わるため、事前の件数と影響件数がズレて当然のことがあります。この場合は件数のズレ=失敗とは限らないので、慌ててROLLBACKせず、別の見分け方(後述の④の再SELECTなど)で確かめましょう。
③ トランザクションで囲む
確認したWHEREで実行に移りますが、その前にトランザクションで囲んで「すぐ戻せる」状態にします。対応しているDBなら、これが安全弁になります。
START TRANSACTION; -- PostgreSQLなら BEGIN;
-- ここで UPDATE / DELETE を実行する
-- 件数と結果を確認してから…
COMMIT; -- 想定どおりなら確定
-- ROLLBACK; -- 少しでもおかしければ取り消し
COMMITするまでは、ROLLBACKで元に戻せます。 「実行 → 確認 → 確定(または取り消し)」を一呼吸の中でできるのが、トランザクションの強みです。COMMITを打つ前は、まだ引き返せます。
ひとつだけ注意。稼働中の本番テーブルでは、トランザクションを開けている間ずっと対象行にロックがかかり続けます。確認に手間取ってトランザクションを長く開けっぱなしにすると、後続のアプリ処理やバッチを止めてしまうことがあります。だから、**②の件数確認(SELECT COUNT(*))はトランザクションの外で先に済ませておき、トランザクションの中は「実行 → 影響件数の確認 → COMMIT/ROLLBACK」だけを手早く**通すのがコツです。確認は丁寧に、でも開けている時間は短く。
④ 実行して、影響件数を②と照合する
トランザクションの中で、本命のUPDATE/DELETEを実行します。実行したら、「何行に影響したか」を必ず確認します。
- 多くのDBやツールは、実行後に「◯ rows affected(◯行に影響)」と返します。出し方はツールで違います:MySQLのコマンドラインなら実行直後に
Rows matched / Changed、psqlならUPDATE 3のように件数が表示され、DBeaverなどのGUIクライアントは結果欄や下部のステータスに更新件数が出ます。自分の使うツールでどこに出るかを、一度確かめておくと迷いません。 - この影響件数が、②のSELECTで見た件数と一致しているかを照合します。
- 一致していれば、狙ったとおりに当たった証拠。違えば、まだ
COMMITしていないのでROLLBACKで戻します(ただし前述の「SET列をWHEREに使う修正」では、ズレても正常なことがあります)。
UPDATEなら、念のため直した行をもう一度SELECTして、値が期待どおりかも目で見ておくと万全です。
⑤ 件数が合っていればCOMMIT、不安なら必ずROLLBACK
最後の確定です。ここだけは、勢いで押さないようにします。
- ②の件数 = ④の影響件数 で、値も期待どおり →
COMMITで確定。 - 件数が違う・値がおかしい・少しでも「あれ?」がある → ためらわず
ROLLBACK。
ROLLBACKは失敗ではありません。「気づいて戻せた」という成功です。 迷ったら戻す。直し直せばいいだけなので、確定を急ぐ理由はどこにもありません。
やってしまいがちな落とし穴
手順の合間で、つい起きやすいところも先に共有します。知っているだけで避けられます。
- WHEREを書く前にUPDATE文を組み立てる:
UPDATE orders SET status='done'まで書いた状態で手が滑ると、全件更新です。WHEREを先に書く癖をつけると安全です。 - 本番と検証の接続先を間違える:同じ画面で本番にも検証にもつなげる環境は、思い込みで本番に打ってしまいがち。実行前に接続先を1回声に出して確認します。
- 自動コミットが有効なまま:ツールによっては1文ごとに即確定され、
ROLLBACKが効きません。切り方もツールで違います——MySQL CLIならSET autocommit=0;、psqlは\set AUTOCOMMIT off、DBeaverなどのGUIはツールバーの自動コミットのトグルで切り替えます。トランザクションを使う前に、自分のツールでの切り方を確認します。 - 複数行を一度に直すときの巻き込み:
WHEREが範囲指定(日付・ステータス)のときほど、②の件数確認が効きます。 - 直したことを記録しない:いつ・どのテーブルを・どんな条件で直したかを残さないと、後で原因調査のときに「謎の変更」になります。変更管理として一行残しておきます。
落とし穴はどれも、②の件数確認と③のトランザクションでほとんど受け止められます。
明日、いちばん小さく試せること
全部を一度に身につけなくて大丈夫です。次にデータ修正を頼まれたとき、ひとつだけ試してみてください。
- 直したい条件を決めたら、まず**その
WHEREでSELECT COUNT(*)を1回**打つ。 - 出た件数が「直したい行数」と合っているかを確かめる。
- 合っていたら、
START TRANSACTION;(またはBEGIN;)と打ってからUPDATE/DELETEを実行する。 - 影響件数が②と一致したら
COMMIT;、少しでも違えばROLLBACK;。
この「先にCOUNT、トランザクションで囲む」の2つを足すだけで、本番データ修正の安心感はぐっと変わります。
「SQLでデータ修正」安全チェックリスト
実行ボタンを押す前に、これだけ確認できているかを見る項目です。コピーして、自分のメモに当ててみてください。全部に○が付かなくても大丈夫なように、必須と推奨の二段に分けてあります。
必須(ここだけは——最大事故の「本番取り違え」「戻せない」を防ぐ最低ライン)
- 接続先が本番で合っているか(検証と取り違えていないか)を確認したか
- 直す前の値を、ダンプ・退避テーブル・メモ(CSV・テキスト)のどれかで控えてあるか
- 直すのと**同じ
WHEREでSELECT COUNT(*)**し、件数が想定どおりか確認したか
推奨(時間と環境が許せば。やれるほど安心が増えます)
-
UPDATE/DELETEの文に、WHEREを先に書いて条件を絞ったか - トランザクション(START TRANSACTION/BEGIN)で囲んでいるか、自動コミットは切れているか(長く開けっぱなしにしない)
- 実行後の影響件数が、事前のSELECT件数と一致したか(SET列をWHEREに使う修正ではズレても正常なことあり)
-
UPDATEなら、直した行をもう一度SELECTして値を確認したか - 少しでも違和感があれば
ROLLBACKできる状態か(まだCOMMITしていないか) - いつ・どのテーブルを・どんな条件で直したかを、記録に一行残したか
忙しい日は、まず必須の3点(接続先・控え・件数確認)だけでも大丈夫。これだけで「本番取り違え」と「戻せない」という最大の事故は止められます。推奨は、できるところから足していけば十分です。
よければ、こちらも
データ修正は、改修や障害対応とつながっています。「直す前に影響を見る」「直したあとに何かあっても落ち着く」型をセットで持っておくと、当日とても楽になります。
- 既存システムの改修|影響範囲を見落とさない調査の順番:そのデータを読み書きしている処理を、事前に洗い出すための1枚です。
- 障害対応runbookテンプレート|初動・切り分け・連絡・記録を1枚に:もし修正後に何か起きても、初動と連絡の型があれば落ち着いて動けます。
- 500エラーが出たら最初に見る5つのログ|場所と確認の順番:データ変更の直後に5xxが出たとき、見る順番つきでたどるための1枚です。

本番のデータ修正がこわいのは、見えないまま戻せない操作をするからでした。でも、先にSELECTで件数を見て、トランザクションで囲んでおけば、「見える」も「戻せる」も自分の手の中に入ります。 今日は次の修正で、SELECT COUNT(*)を1回挟むだけで十分です。その一手が、震える指を、落ち着いて押せる指に変えてくれます。
ほかの実務ヒントは記事一覧からどうぞ。保守運用の小さな備えを、メールでも少しずつお届けしています。