バインド変数とは、SQL文の中で値を入れる場所をあらかじめ決めておく方法のことです。
まるで「穴あき問題」のように、後から答えを埋められるようになっています。
たとえば、「従業員番号が○○の人を探して」という命令を、○○の部分を変えながら何度も使いたいときに便利です。
毎回新しいSQL文を作る必要がなく、○○の部分だけを変えて使い回しができます。
なぜバインド変数を使うの?

パフォーマンスが向上する
データベースは一度処理したSQL文を記憶しています。バインド変数を使うと、同じ形のSQL文として認識されるため、処理が早くなります。
セキュリティが向上する
悪意のあるコードがSQL文に混入することを防げます。これを「SQLインジェクション対策」といいます。
コードが読みやすくなる
値を直接SQL文に書き込むより、整理された形で管理できます。
データベース別の書き方

Oracle Database
Oracleでは、コロン(:)を使って変数名を指定します。
-- 基本的な使い方
SELECT * FROM employees WHERE employee_id = :emp_id;
-- 複数の変数を使う場合
SELECT * FROM employees
WHERE department_id = :dept_id
AND salary > :min_salary;
説明と例を分けて考えてみましょう
説明: :emp_id
や:dept_id
がバインド変数です。
実行するときに、これらの変数に具体的な値を設定します。
例: 従業員番号100の人を検索したい場合、emp_id
に100を設定してSQL文を実行します。
PostgreSQL
PostgreSQLでは、ドル記号($)と数字を組み合わせて使います。
-- 基本的な使い方
SELECT * FROM employees WHERE employee_id = $1;
-- 複数の変数を使う場合
SELECT * FROM employees
WHERE department_id = $1
AND salary > $2;
説明: $1
は1番目のパラメータ、$2
は2番目のパラメータを表します。
例: 部署番号10で給与が50000以上の従業員を検索する場合、$1に10、$2に50000を設定します。
MySQL / SQLite
MySQLやSQLiteでは、クエスチョンマーク(?)を使います。
-- 基本的な使い方
SELECT * FROM employees WHERE employee_id = ?;
-- 複数の変数を使う場合
SELECT * FROM employees
WHERE department_id = ?
AND salary > ?;
説明: ?
の順番で値が設定されます。左から順に1番目、2番目となります。
例: 最初の?
に部署番号、2番目の?
に最低給与を設定します。
プログラムでの使用例

Python(psycopg2でPostgreSQL)
import psycopg2
# データベースに接続
conn = psycopg2.connect(database="sample_db")
cur = conn.cursor()
# バインド変数を使ったクエリ実行
emp_id = 100
cur.execute("SELECT * FROM employees WHERE employee_id = %s", (emp_id,))
results = cur.fetchall()
Python(sqlite3でSQLite)
import sqlite3
# データベースに接続
conn = sqlite3.connect('sample.db')
cur = conn.cursor()
# バインド変数を使ったクエリ実行
emp_id = 100
cur.execute("SELECT * FROM employees WHERE employee_id = ?", (emp_id,))
results = cur.fetchall()
Java(JDBCでMySQL)
String sql = "SELECT * FROM employees WHERE employee_id = ?";
PreparedStatement pstmt = connection.prepareStatement(sql);
pstmt.setInt(1, 100);
ResultSet rs = pstmt.executeQuery();
実践的な使用例

検索機能での活用
-- ユーザーが入力した条件で検索
SELECT * FROM products
WHERE category = :category
AND price BETWEEN :min_price AND :max_price
AND stock > 0;
この例では、ユーザーが選んだカテゴリと価格範囲で商品を検索できます。
データ更新での活用
-- 従業員情報の更新
UPDATE employees
SET salary = :new_salary,
department_id = :new_dept_id
WHERE employee_id = :emp_id;
この例では、特定の従業員の給与と部署を更新できます。
データ挿入での活用
-- 新しい注文の登録
INSERT INTO orders (customer_id, product_id, quantity, order_date)
VALUES (:customer_id, :product_id, :quantity, :order_date);
この例では、新しい注文情報をデータベースに登録できます。
データベース別まとめ表
データベース | バインド変数の書き方 | 特徴 | 使用例 |
---|---|---|---|
Oracle | :変数名 | 名前でわかりやすい | :emp_id |
PostgreSQL | $1 , $2 … | 順番で管理 | $1 , $2 |
MySQL | ? | シンプル | ? |
SQLite | ? | シンプル | ? |
SQL Server | @変数名 | 名前でわかりやすい | @emp_id |
よくある質問

Q: バインド変数を使わないとどうなるの?
A: 毎回新しいSQL文として処理されるため遅くなります。また、SQLインジェクション攻撃の危険性も高まります。
Q: バインド変数はテーブル名や列名にも使える?
A: 基本的には使えません。バインド変数は値の部分でのみ使用できます。
Q: 同じバインド変数を複数箇所で使える?
A: はい、できます。同じ変数名なら同じ値が設定されます。
まとめ
バインド変数は、SQLを効率的で安全に使うための重要な技術です。
最初は少し複雑に感じるかもしれませんが、慣れてしまえばとても便利な機能です。
特に、繰り返し実行するSQL文やユーザーからの入力を扱う場合には、必ずバインド変数を使うようにしましょう。
パフォーマンスとセキュリティの両方を向上させることができます。
データベースによって書き方が少し違いますが、基本的な考え方は同じです。
コメント