Parameter index out of range (2 > number of parameters, which is 1). は、PreparedStatement の setInt・setString で指定した番号が、SQL の ? の数より大きい(または 0 以下)ときのエラーです。 この形は MySQL Connector/J のメッセージで、MySQL のバグ票にも同じ形(Parameter index out of range (4 > number of parameters, which is 2).)が載っています。

ドライバによって、同じ間違いでもエラー文が違います。 確認環境では次のように表示されました。

間違い PostgreSQL(pgJDBC 42.7.2) MySQL(MariaDB Connector/J 2.7.6)
? は1つなのに setString(2, ...) The column index is out of range: 2, number of columns: 1. Could not set parameter at position 2 (values was 'x')
setInt(0, ...)(0 から数えた) The column index is out of range: 0, number of columns: 1. Could not set parameter at position 0 (values was 1)
'?' と引用符で囲んだ The column index is out of range: 1, number of columns: 0. Could not set parameter at position 1 ...
? に値を入れずに実行 No value specified for parameter 1. Parameter at position 1 is not set

PostgreSQL のドライバは、?(パラメータ)のことも「column」と表示します。 number of columns: 0 は「この SQL には ? が1つも無い」という意味です。

確認環境:OpenJDK 21、PostgreSQL 16.15 と pgJDBC 42.7.2、MySQL 8.0.46 と MariaDB Connector/J 2.7.6 で再現しました。MySQL Connector/J は手元で使えなかったため、そのメッセージは MySQL のバグ票の記載を示しています(確認日 2026年10月11日)。

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「Parameter index out of rangeの直し方|JDBC」

番号は 1 から数える

PreparedStatement ps = con.prepareStatement(
    "SELECT name FROM j_users WHERE id = ?");
ps.setInt(1, 1);            // 1つ目の ? は 1

Java の公式ドキュメント(PreparedStatement)では、parameterIndex は「最初のパラメータが 1、2番目が 2」と説明され、SQL の ? に対応しない番号では SQLException になると書かれています。配列やリストのつもりで 0 から数えると、エラーになります。

'?' を引用符で囲むと、? として扱われない

// 間違い
con.prepareStatement("SELECT name FROM j_users WHERE name = '?'");
// 正しい
con.prepareStatement("SELECT name FROM j_users WHERE name = ?");

'?' は「? という文字」になり、パラメータではなくなります。 SQL の中の ? が0個になるので、setString(1, ...) が「範囲外」になりました。値を入れるのはドライバの仕事なので、文字列の値でも引用符は書きません。

LIKE の % はどこに書くか

書き方 結果(両方のドライバ)
"... WHERE name LIKE '%?%'" + setString(1, "山") エラー(? が引用符の中にある)
"... WHERE name LIKE ?" + setString(1, "%山%") 山田 が取れた

% は、SQL ではなく、渡す値の側に付けます。 値に %・_ が含まれる可能性があるときは、エスケープも必要です。

取り出すとき(getString)の番号の間違い

ResultSet から値を取り出すときも、番号の間違いで似たエラーになります。

書いたコード(SELECT name ... で1列) PostgreSQL MySQL(MariaDB Connector/J)
rs.getString(2) The column index is out of range: 2, number of columns: 1. No such column: 2
rs.getString(0) The column index is out of range: 0, number of columns: 1. No such column: 0
rs.getString("email")(SELECT していない列) The column name email was not found in this ResultSet. No such column: 'email'. 'email' must be in [name, j_users.name]

PostgreSQL のドライバでは、setString の間違いも getString の間違いも、同じ The column index is out of range でした。 スタックトレースの行番号で、set と get のどちらで起きたかを確かめます。列は名前で取り出す(rs.getString("name"))と、SELECT の列の順番を変えても壊れません。

? の数を数える方法

SQL を文字列の連結で組み立てていると、? の数と set の数がずれやすくなります。

String sql = "UPDATE j_users SET name = ?, email = ? WHERE id = ?";
long count = sql.chars().filter(c -> c == '?').count();   // 3
確かめること 内容
? の数 引用符の中の ? は数えない
set の呼び出しの番号 1 から順に、抜けや重複が無いか
条件によって ? が増える SQL 条件を足したときに、set も足しているか

条件によって AND x = ? を足す SQL は、番号を変数で数えながら set すると、ずれを防げます。

List<Object> params = new ArrayList<>();
StringBuilder sql = new StringBuilder("SELECT * FROM j_users WHERE 1 = 1");
if (name != null)  { sql.append(" AND name LIKE ?"); params.add("%" + name + "%"); }
if (email != null) { sql.append(" AND email = ?");   params.add(email); }
try (PreparedStatement ps = con.prepareStatement(sql.toString())) {
    for (int i = 0; i < params.size(); i++) ps.setObject(i + 1, params.get(i));
    ...
}

確認の手順(チェックリスト)

順番 確認すること 方法
1 エラーは set か get か スタックトレースの行
2 ? の数 引用符の中の ? を除いて数える
3 番号が 1 から始まっているか setInt(0, ...) が無いか
4 '?'・'%?%' と書いていないか 値の側に % を付ける
5 条件で ? が増える SQL set も同じ条件で増やす
6 get なら SELECT の列 列名で取り出す

よくある質問

Q. JDBC で MySQL につなぐ基本の書き方は。 A. 既存の記事「Java JDBCでMySQL接続|PreparedStatementとCRUD」で扱っています。

Q. ドライバ自体が見つからないエラーは。 A. 関連記事の「No suitable driver foundの原因と直し方|Java JDBC」で扱っています。

まとめ

  • set の番号が、SQL の ? の数と合っていないエラー
  • 番号は 1 から。0 から数えるとエラー
  • '?'・LIKE '%?%' は ? にならない。% は値の側に付ける
  • PostgreSQL のドライバは The column index is out of range と表示し、get の間違いでも同じ文
  • 条件で ? が増える SQL は、パラメータをリストで管理する

参考・出典

確認日はいずれも 2026年10月11日です。

  • Java SE 21 API「PreparedStatement」:https://docs.oracle.com/en/java/javase/21/docs/api/java.sql/java/sql/PreparedStatement.html
  • MySQL Bugs「Bug #117294 Updatable ResultSet fails with 'Parameter index out of range'」:https://bugs.mysql.com/bug.php?id=117294

本記事の内容は、ご自由にお使いください。
ご利用の際は、出典として本ページへのリンクを記載いただけますようお願いします。

(記載例)出典:株式会社RJC「Parameter index out of rangeの直し方|JDBC」

株式会社RJC ― SI事業・SES事業・AI駆動開発。RJCは一緒に成長を楽しめる会社です。

WE ARE HIRING

RJCで一緒に開発しながら、
成長を楽しみませんか?

RJCは、Web・モバイル・AIを活用した開発プロジェクトで、テックリードやPM・PMOも活躍するシステム開発会社です。会社を知る、待遇を確かめる、話を聞いてみる。気になるところ見てみてください!

  • 127日年間休日
  • 12時間平均残業時間
  • 毎日ガチャ遊びココロも大切にする福利厚生。アマギフなどの賞品ラインナップ!

ほかにも、チケットレストラン、書籍読み放題、2年ごとの慰労報奨(休暇 or 金一封)、11期連続の黒字決算。

ABOUT RJC RJCがどんな会社か知る 考え方、研修、働き方、福利厚生、社員の前職まで。RJCのことが丸わかり! RJC丸わかりページへ JOB DESCRIPTION 仕事内容・待遇を見てみる 仕事内容、給与・待遇、選考の流れ。経験者も未経験も!応募前に知りたいこと、まとめました! 募集要項を見る ENTRY エントリーする エントリーは1〜2分・履歴書不要です。まずは話を聞いてみたい、という方でも歓迎です! エントリーフォームへ

RJCで一緒に開発しながら、 成長を楽しみませんか?