データベースの用語一覧へ
このページの目次

プリペアドとは?

読み方:プリペアド

最終更新:2026/08/18

3秒でわかる

SQLの文の形と、そこへ埋める値を分けて送る仕組み。値が文として解釈されないため、SQLインジェクションを根本から防げます。

もう少し詳しく

どういうものか

プリペアドステートメントは、SQLの文の形と、そこに埋める値を別々にデータベースへ渡す仕組みです。まず ?$1 のような穴あきのSQLを送って解析させ、そのあとで値を送ります。値は最初から「文の一部」ではなく「データ」として扱われるため、中に '-- が混ざっていても文の意味が変わりません。

なぜ必要か

文字列連結でSQLを組み立てると、入力された文字がSQLの一部として解釈されます。ログインフォーム' OR '1'='1 と入れられただけで、条件が常に真になり全ユーザーの行が返ります。これがSQLインジェクションで、情報漏えい事故の代表例です。入力をエスケープして防ぐ方法もありますが、1か所でも書き忘れれば穴になります。値を別便で送るなら書き忘れようがありません。入力を疑う場所が1か所に集まるので、レビューでも見落としが起きにくくなります。

具体例

import sqlite3 conn = sqlite3.connect("shop.db") cur = conn.cursor() name = "' OR '1'='1" # 危険 文字列連結 cur.execute("SELECT * FROM users WHERE name = '" + name + "'") # 安全 値は別に渡す cur.execute("SELECT * FROM users WHERE name = ?", (name,)) print(cur.fetchall()) # 0件

同じ文を繰り返し実行するときは、解析結果が再利用されるため速度面でも有利になります。

つまずきやすいところ

プレースホルダテーブル名や列名に使おうとして失敗する例が多く見られます。SELECT * FROM ? は動きません。穴を空けられるのは値の位置だけで、文の構造は先に確定している必要があります。並び替えの列名を画面から受け取るなら、許可リストと突き合わせて選ぶ形にします。もうひとつは IN 句で、要素数の分だけ ? を並べる必要があります。

似た用語との違い

役割
プリペアドステートメント文と値を分けて送る仕組み
エスケープ危険な文字を無害な表記へ書き換える処理
バインド変数プレースホルダに渡す値そのものの呼び名


覚え方

先に文の設計図を渡し、あとから材料を渡す方式です。材料が文の一部として読み直されることはない、という点だけ押さえておけば使い方を間違えません。

対応する書き方は言語ごとに名前が違いますが、文と値を分けて渡すという中身はどれも同じです。

知識のつながり

サイドバーと同じ推奨ルート・関連語を、まとめて確認できます。

現在地プリペアドDB

LEARN BY DOING

この用語を、教材で使ってみる

直接関連する編と、その編を含むコースです。用語だけで終わらず、ブラウザ上で実際に手を動かせます。

SQL・データベースコースの全編を見る