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

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

ただいまの
回答率

90.62%

  • Java

    13466questions

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

  • SQL

    2309questions

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

select文の結果を変数に取得したい

受付中

回答 2

投稿

  • 評価
  • クリップ 0
  • VIEW 7,913

touch

score 35

 現在、SQL文の発行によりデータベースアクセスを行うdaoクラスを作成中です。
 このクラスの中に、ID自動採番を行うメソッド(呼び出し元に戻り値integer型のIDが代入された変数を返す)を作っているのですが、select文の問い合わせ結果をどのように変数に取得すればよいのかがわからず困っています。自分でこうではないかというソースコードを作成したのですが、何か違うような気もしています。
宜しければどうかご助力いただけませんでしょうか?
以下、該当メソッド部分のソースコードになります。

    /* フィールド変数 */
    private Connection con;        // 接続オブジェクト
    private PreparedStatement ps;  // ステートメント
    private ResultSet rs;          // SELECT文の結果を受け取る


        /* param con 接続オブジェクト */
    public Integer getId(Connection con){
        
        /* SQL文を作成する */
        StringBuilder sb = new StringBuilder();
        sb.append("SELECT ");
        sb.append("MAX(ID) + 1 ");
        sb.append("AS ID ");
        sb.append("FROM ");
        sb.append("TABLE_LIST "); 
        
//IDを格納する変数numを初期化
Integer num = 0;

        try {
            
            // プリペアードステートメントを生成する
            ps= con.prepareStatement(sb.toString());
            
            // SQL文発行
            rs = ps. executeQuery();

   num = rs.getInt("ID"); //"ID"という文字列から果たして結果が取得できるのでしょうか?

        }catch(Exception e){
            e.printStackTrace();

        }finally{
            try{

                // 後処理を行う
                if(ps!=null) ps.close();
                if(ps!=null) ps.close();
                if(con!=null) con.close();

            }catch(SQLException e){
                e.printStackTrace();
            }
        }

//呼び出し元へ返す
        return num;
    }


以上になります。宜しくお願い致します。

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

0

フィールド名で取得しようとすると、データベースの種類によっては大文字、小文字のどちらかしか使えないケースが出てきます。
列の順序(1から始まる)を指定するResultSet#getInt(int)を使用した方が確実です。


また、ご質問のポイント以外にもいくつか改善した方が良いと思われる箇所があります。
con,ps,rsはフィールドにする意味が無いので、必要になった時点でローカル変数を宣言するようにした方が良いでしょう。
・ Java7以降ではtry-with-resources文を使用した方が簡潔に書けます。
conはメソッドを呼び出している側で接続を切断するようにした方が良いです。(開けた人が閉じる)


以上を踏まえると、こんな感じになります。

// Java7以降

// import java.sql.*;

/* param con 接続オブジェクト */
public Integer getId(Connection con) {

    /* SQL文を作成する */
    StringBuilder sb = new StringBuilder();
    sb.append("SELECT ");
    sb.append("MAX(ID) + 1 ");
    sb.append("AS ID ");
    sb.append("FROM ");
    sb.append("TABLE_LIST ");

    //IDを格納する変数numを初期化
    Integer num = 0;

    // プリペアードステートメントを生成する
    try (PreparedStatement ps = con.prepareStatement(sb.toString())) {
        // SQL文発行
        try (ResultSet rs = ps.executeQuery()) {
            num = rs.getInt(1);
        }
    } catch (Exception e) {
        e.printStackTrace();
    }

    //呼び出し元へ返す
    return num;
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/05/10 22:41

    ご回答有難うございます。
    ご回答をもとに自身で調べていたところ少しずつ意味がわかってきました。
    あとは自力で考えてみたいと思います。
    重ねて感謝申し上げます。

    キャンセル

0

SELECT MAX(ID) + 1
は止めた方が良いかも。

取得された MAX(ID) + 1 のデータがINSERTされる前に、同時ユーザがいれば、重複してしまうことになります。最大値の管理テーブルを作り、以下の様に処理をした方が良いのでは?

主処理のsession(トランザクション)開始

最大値取得用のsession(トランザクション)開始

最大値管理テーブルをロック

最大値を取得、カウントアップしてコミット(ロック解除)

主処理

主処理のsessionをコミット(またはロールバック)

※ 主処理でこけたら飛び番ができます。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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

  • ただいまの回答率 90.62%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Java

    13466questions

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

  • SQL

    2309questions

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