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

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

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

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

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

Q&A

解決済

3回答

4724閲覧

try-with-resources文のprepareStatementについて

tyai

総合スコア5

Java

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

SQL

SQL(Structured Query Language)は、リレーショナルデータベース管理システム (RDBMS)のデータベース言語です。大きく分けて、データ定義言語(DDL)、データ操作言語(DML)、データ制御言語(DCL)の3つで構成されており、プログラム上でSQL文を生成して、RDBMSに命令を出し、RDBに必要なデータを格納できます。また、格納したデータを引き出すことも可能です。

0グッド

0クリップ

投稿2020/12/24 06:28

前提・実現したいこと

フォームから送信されたIDを基に、DBから商品情報を取り出すメソッドを作っています。
現在try文で二重で囲んでいますが、1つだけにしたいです。
この場合、「psmt.setInt(1, id)」はどこにいれるべきなんでしょうか。

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

try (Connection con = getConnection(); PreparedStatement psmt = con.prepareStatement(sql.toString()); ResultSet rs = psmt.executeQuery()) { psmt.setInt(1, id); 上記の形でsetIntをtry文の中に入れてしまうと、 java.sql.SQLException: No value specified for parameter 1 というエラーが発生してしまいます。 デバッグではフォームからIDはちゃんと送信されていますので、文法が間違っているのかなと思っています・・・

該当のソースコード

public ProductBean findOne(int id) throws ClassNotFoundException, SQLException { ProductBean productBean = new ProductBean(); StringBuilder sql = new StringBuilder(); sql.append("select product_ID, ");      ・・・省略・・・     sql.append("from t_product "); sql.append("where product_ID=?"); try (Connection con = getConnection(); PreparedStatement psmt = con.prepareStatement(sql.toString())) { psmt.setInt(1, id); try (ResultSet rs = psmt.executeQuery()) { while (rs.next()) { productBean.setId(rs.getInt("product_ID"));            ・・・省略 } } } return productBean; }

試したこと

try (Connection con = getConnection(); PreparedStatement psmt = con.prepareStatement(sql.toString()); ResultSet rs = psmt.executeQuery(); psmt.setInt(1, id)){

トークンに構文エラーがあります。構成の位置が間違っています。

上記のエラーが出てしまいます。

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

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

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

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

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

guest

回答3

0

ベストアンサー

1. 手順エラー

まず最初のエラーは実行時エラーです。javahackさんの解説のとおり、psmt.executeQuery()を実行する前に?変数は全てバインドされていなければならない。

2. try-wth-resourcesの構文エラー

2番目のエラーは、shiketaさんが指摘されていますが、構文エラーです。try () {}()の中に何が書けるか。リソースの『宣言文』を複数書ける。リソースはjava.lang.AutoCloseableを実装していなければなrない。

The try-with-resources Statement

psmt.setInt(1, id);はリソースの宣言文ですか。いいえ違います。だからコンパイルエラーになります。

結論

あなたの望むようにtry()一つのなかに、宣言文と宣言文以外の文を一緒に書くことはできません。

勧められない回避策

こっそり教えますが、宣言文は書けます。良い子は真似してはいけません。

Java

1try (Connection con = getConnection(); 2 PreparedStatement psmt = con.prepareStatement(sql.toString()); 3 AutoCloseable a = new AutoCloseable() { 4 { psmt.setInt(1, id); } 5 @Override public void close() throws Exception {} 6 }; 7 ResultSet rs = psmt.executeQuery()) { 8 while (rs.next()) { 9 productBean.setId(rs.getInt("product_ID")); 10 // ・・・省略 11 } 12} catch (ClassNotFoundException | SQLException e) { 13 throw e; 14} catch (Exception e) { 15 throw new SQLException(e); 16}

推奨しない理由

回避コードpsmt.setInt(1, id);から例外が出ると困る。何のためにtryを使うのか考えてください。
同様にリソース宣言の初期化式からも例外が出ることを考えてください。

投稿2020/12/29 02:07

編集2020/12/29 21:16
xebme

総合スコア1081

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

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

0

try (Connection con = getConnection();
PreparedStatement psmt = con.prepareStatement(sql.toString());
psmt.setInt(1, id);
ResultSet rs = psmt.executeQuery()){

この形にしても下記のエラーが出てしまいます。。
トークンに構文エラーがあります。構成の位置が間違っています

ドキュメントには、こうある。 https://docs.oracle.com/javase/jp/7/technotes/guides/language/try-with-resources.html

try-with-resources 文は、1 つ以上のリソースを宣言する try 文です。リソースは、プログラムでの使用が終わったら閉じられなければいけないオブジェクトです。

PreparedStatement psmt = con.prepareStatement(sql.toString());ResultSet rs = psmt.executeQuery()は、「リソースを宣言する」文だが、psmt.setInt(1, id);は異なる。だから構成の位置が間違っていますとなる。

投稿2020/12/28 05:10

shiketa

総合スコア3971

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

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

tyai

2020/12/28 06:31

なるほど、では発生している問題・エラーメッセージで書いた文はあっている気がするんですが、エラーが出てしまうのは何故でしょうか、、
shiketa

2020/12/29 03:07 編集

> 発生している問題・エラーメッセージで書いた文はあっている気がするんですが... 気のせいです。javahackさんが丁寧に書いてくれているじゃないですか。 年賀状の季節なので、こういう例えだとわかりますかね。ハガキをポストに入れてから宛名を書きますか?おそらく普通のヒトは、ハガキに宛名を書いて(`psmt.setInt(1, id)`)からポストに投函(`psmt.executeQuery()`)します。
guest

0

2重の時と1つの時で文の順番が違っています。

Java

1//2重の時 2 psmt.setInt(1, id); 3 ResultSet rs = psmt.executeQuery(); 4//1つの時 5 ResultSet rs = psmt.executeQuery(); 6 psmt.setInt(1, id);

投稿2020/12/26 17:14

javahack

総合スコア1088

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

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

tyai

2020/12/28 03:33

try (Connection con = getConnection(); PreparedStatement psmt = con.prepareStatement(sql.toString()); psmt.setInt(1, id); ResultSet rs = psmt.executeQuery()){ この形にしても下記のエラーが出てしまいます。。 トークンに構文エラーがあります。構成の位置が間違っています
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問