質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

デバッグ

デバッグはプログラムのバグや欠陥を検知し、開発中のバグを取り除く為のプロセスを指します。

servlet

Servletとは、Webページの動的な生成やデータ処理などをサーバ上で実行するために、Javaで作成されたプログラムです。 ショッピングサイトやオンラインバンキングといった、動的なウェブサイトの構築に用いられています。

Q&A

解決済

1回答

4864閲覧

PreparedStatementのsetString文が上手く動作しない

haram

総合スコア1

MySQL

MySQL(マイエスキューエル)は、TCX DataKonsultAB社などが開発するRDBMS(リレーショナルデータベースの管理システム)です。世界で最も人気の高いシステムで、オープンソースで開発されています。MySQLデータベースサーバは、高速性と信頼性があり、Linux、UNIX、Windowsなどの複数のプラットフォームで動作することができます。

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

デバッグ

デバッグはプログラムのバグや欠陥を検知し、開発中のバグを取り除く為のプロセスを指します。

servlet

Servletとは、Webページの動的な生成やデータ処理などをサーバ上で実行するために、Javaで作成されたプログラムです。 ショッピングサイトやオンラインバンキングといった、動的なウェブサイトの構築に用いられています。

0グッド

0クリップ

投稿2021/04/03 14:17

検索システムで条件によって変化するSQL文を作成したい。

Java(Servlet/jsp)で検索システムを作っています。
検索条件によって変化するSQL文を作成中にに以下のエラーメッセージが発生しました。
PreparedStatementのsetString文が上手く動作しないのですが、原因がわかる方教えていただきたいです。

発生している問題・エラーメッセージ

java.sql.SQLException: Parameter index out of range (2 > number of parameters, which is 1).

該当のソースコード

public List<Books> search(String genre,String author, String title){ StringBuilder sql = new StringBuilder(); sql.append ("select * from books where "); boolean genreFlg = false; boolean authorFlg = false; boolean titleFlg = false; boolean andFlg = false; List<Books> result = new ArrayList<Books>(); if(!"".equals(genre)) { sql.append("genre like ?"); genreFlg = true; andFlg = true; } if(!"".equals(author)) { if (andFlg) sql.append(" AND "); sql.append("author like ?"); authorFlg = true; andFlg = true; } if(!"".equals(title)) { if (andFlg) sql.append(" AND "); sql.append("title like ?"); titleFlg = true; andFlg = true; } try { Connection con = DatabaseManager.getConnention(); pstmt = con.prepareStatement(sql.toString()); if(genreFlg) { pstmt.setString(1, "%"+genre+"%"); } if(!genreFlg && authorFlg) { pstmt.setString(1, "%"+author+"%"); }else if(genreFlg && authorFlg) { pstmt.setString(2, "%"+author+"%"); } if(!genreFlg && !authorFlg && titleFlg) { pstmt.setString(1, "%"+title+"%"); }else if (genreFlg && authorFlg && titleFlg) { pstmt.setString(3, "%"+title+"%"); }else if (genreFlg || authorFlg && titleFlg){ pstmt.setString(2, "%"+title+"%"); } rs = pstmt.executeQuery(); while(rs.next()) {・・・・・・・・・

試したこと

デバッグで変数の動きをみたところ、PreparedStatementのsetString文で下記が表示されており、genre変数をsetString出来ていないようでした。

com.mysql.cj.jdbc.ClientPreparedStatement: select * from books where genre like ** NOT SPECIFIED **

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

java

1} else if (genreFlg || authorFlg && titleFlg){ 2 pstmt.setString(2, "%"+title+"%"); 3}

&&の評価が||より優先されるので、
上記は、以下のように評価されます。

java

1} else if (genreFlg || (authorFlg && titleFlg)){ 2 pstmt.setString(2, "%"+title+"%"); 3}

結果、grenreFlg が trueであれば、titleFlgがfalseでも通ってしまい、
パラメータが1つなのに、2つsetStringされるため

java.sql.SQLException: Parameter index out of range (2 > number of parameters, which is 1).

の例外が発生します。

以下のように修正すればよいかと思います。

java

1} else if ((genreFlg || authorFlg) && titleFlg){ 2 pstmt.setString(2, "%"+title+"%"); 3} 4

ちなみに、プリペアドステートメントのインデックスは以下のようにすれば自動でインクリメントされるので、煩雑なif文の判定は不要になるかと思います。

java

1 int pIndex = 1; 2 if(genreFlg) { 3 pstmt.setString(pIndex++, "%"+genre+"%"); 4 } 5 6 if(authorFlg) { 7 pstmt.setString(pIndex++, "%"+author+"%"); 8 } 9 10 if(titleFlg) { 11 pstmt.setString(pIndex++, "%"+title+"%"); 12 } 13

投稿2021/04/03 16:54

編集2021/04/03 17:04
momon-ga

総合スコア4826

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

haram

2021/04/03 19:50

解決しました。ありがとうございます!! またインクリメントのご教示ありがとうございます。 綺麗なコードを書けるよう勉強を続けます!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問