1. 導入
データベース管理において、データの「削除」は最も慎重に行うべき操作の一つです。特にDELETE文は、WHERE句を一つ書き忘れるだけでテーブル内の全データを消失させるリスクを孕んでいます。本記事では、SQLiteにおけるDELETE文の基本から、現場でトラブルを避けるための安全な実装テクニックまでを解説します。
2. 基礎知識
DELETE文は、テーブルから特定の行を物理的に削除するためのコマンドです。
基本構文は「DELETE FROM テーブル名 WHERE 条件式;」となります。ここで重要なのは、WHERE句は削除対象を絞り込むためのフィルターであるという点です。もしWHERE句を省略すると、そのテーブルに存在するすべてのデータが対象となり、一瞬でテーブルが空になってしまいます。
3. 実装/解決策
実務でDELETEを実行する際は、いきなりDELETE文を打つのではなく、必ず以下の手順を徹底してください。
1. SELECTで確認: 削除予定の条件でSELECT文を実行し、意図した行だけが抽出されているか確認する。
2. バックアップ(またはトランザクション): 重要な操作の前には、可能であればテーブルのバックアップを取るか、トランザクションを開始して「元に戻せる状態」にする。
3. 件数を確認: 削除前に変更される行数を確認する。
4. サンプルプログラム
以下は、PythonからSQLiteを操作し、安全にデータを削除するサンプルコードです。トランザクションを活用することで、誤操作時のロールバック(取り消し)を可能にしています。
import sqlite3
データベース接続
conn = sqlite3.connect('example.db')
cursor = conn.cursor()
try:
# トランザクション開始
conn.execute("BEGIN")
# 1. 削除前に件数を確認(安全策)
target_id = 2
cursor.execute("SELECT count() FROM user WHERE id = ?", (target_id,))
count = cursor.fetchone()[0]
if count > 0:
# 2. 削除実行
cursor.execute("DELETE FROM user WHERE id = ?", (target_id,))
print(f"{count} 件のデータを削除しました。")
# 3. 確定(コミット)
conn.commit()
else:
print("削除対象が見つかりません。")
except Exception as e:
# エラー発生時はロールバックして変更を破棄
conn.rollback()
print(f"エラーが発生しました。変更をロールバックします: {e}")
finally:
conn.close()
5. 応用・注意点
現場で陥りやすいバグやトラブルを回避するための補足です。
・DELETE vs TRUNCATE: SQLiteにはTRUNCATE文が存在しません。テーブルを空にする場合もDELETE文を使用しますが、大量のデータを消す場合は処理時間がかかることがあります。
・WHERE句の過信禁物: 外部キー制約がある場合、CASCADE設定がなされていると、予期せぬ関連レコードまで連鎖削除される可能性があります。設計書で制約を確認してください。
・論理削除の検討: 「本当に消してよいデータか」を常に問いましょう。物理削除(DELETE)を行うと復旧は困難です。削除フラグカラム(is_deletedなど)を用意する「論理削除」を運用ルールに含めることも、DBAとして検討すべき重要な選択肢です。

コメント