- PR -

例外処理内で宣言した変数の返し方

1
投稿者投稿内容
うる
常連さん
会議室デビュー日: 2005/10/16
投稿数: 41
投稿日時: 2005-10-16 14:21
ResultSet rsをretunで返したいのですが、上手く返せません。
例外処理部分で宣言した変数をretunで返したい時は、
どうすればよろしいのでしょうか?
ResultSet rsを例外処理の外で宣言する方法だと、
初期化の仕方が分からないので、retunで返せません。


ResultSet getDbField(String aFiled, String aTable){
String filed = "";
int i=0;

connectionDb(READ_ONLY); //DBへの接続

StringTokenizer tokenFiled = new StringTokenizer(aFiled,",");

while(tokenFiled.hasMoreTokens()){
//フィールド名の間に,を入れる
if(i != 0){
filed += ",";
}
i++;

filed += tokenFiled.nextToken();
}

try{
PreparedStatement prdStt=db.prepareStatement("SELECT " + filed + " FROM " + aTable);
ResultSet rs = prdStt.executeQuery();
closeDb(); // DBの切断
return rs;
}catch (Exception e){

}
}
Cafe
会議室デビュー日: 2005/09/10
投稿数: 12
投稿日時: 2005-10-16 15:10
失礼します。

単純にtry/catchの前に
ResultSet rs = null;
とかって宣言すれば、catchの中でもreturn出来そうですが如何でしょうか。
(例外時はNullを返す事になりますが・・・)

ちなみに・・・
もし、私がDBAccessメソッドを作るのであれば、値の取り出しまでをDBAccessで行って、取り出した値をreturnする形に設計します。

#・・と、他の現場ではどうなんでしょうかね?(^^;;;
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2005-10-16 17:01
セオリー的には例外時にResultSetを返す必要はないのではと思います。
(例外が発生した場合、その処理によって得られた結果が正しい保障はない)
なので、
コード:
ResultSet rs = null;
try{ 
    PreparedStatement prdStt=db.prepareStatement("SELECT " + filed + " FROM " + aTable); 
    rs = prdStt.executeQuery(); 
//    closeDb(); // DBの切断 
    return rs; 
}catch (Exception e){ 
    return rs;
}finally{
    closeDb(); // DBの切断 
}


もしくは、もっと簡単に
コード:
try{ 
    PreparedStatement prdStt=db.prepareStatement("SELECT " + filed + " FROM " + aTable); 
    return prdStt.executeQuery(); 
}catch (Exception e){ 
    return null;
}finally{
    closeDb(); // DBの切断 
}


でいいような気がします。

ちなみに、本来の目的は変数のスコープの問題ですよね。
{}ブロック内で宣言した変数は、そのブロック内でしか使用できません。
ブロックの外側で指定した変数は、内側の全てで使用可能です。
ちょま吉
大ベテラン
会議室デビュー日: 2004/08/04
投稿数: 112
投稿日時: 2005-10-16 20:21
あの、、、。
変な質問かもしれませんが、
ResultSetを返すのは良いのですが、DBコネクションをクローズしてもResultSetって利用できるのでしょうか?
試してみれば良いのですが、現在DB環境が無く、構築するのも手間がかかるので。

ちなみにPreparedStatementとResultSetの関係は、j2sdk1.4のResultSetのJavadocには下記のようにかかれています。
引用:
ResultSet オブジェクトは、このオブジェクトを生成した Statement オブジェクトが閉じられるとき、再実行されるとき、あるいは一連の複数の結果から次の結果を取り出すために使われるときに、自動的に閉じられます。

Cafe
会議室デビュー日: 2005/09/10
投稿数: 12
投稿日時: 2005-10-17 10:24
引用:

ちょま吉さんの書き込み (2005-10-16 20:21) より:
あの、、、。
変な質問かもしれませんが、
ResultSetを返すのは良いのですが、DBコネクションをクローズしてもResultSetって利用できるのでしょうか?
試してみれば良いのですが、現在DB環境が無く、構築するのも手間がかかるので。

ちなみにPreparedStatementとResultSetの関係は、j2sdk1.4のResultSetのJavadocには下記のようにかかれています。
引用:
ResultSet オブジェクトは、このオブジェクトを生成した Statement オブジェクトが閉じられるとき、再実行されるとき、あるいは一連の複数の結果から次の結果を取り出すために使われるときに、自動的に閉じられます。





orz(←言われるまで気が付かなかった人・・・(^^;;; )
全くその通りです。
コネクションをcloseしてしまっては、ResultSet使えませんね。

YasT
会議室デビュー日: 2005/10/17
投稿数: 2
投稿日時: 2005-10-17 14:05
YasTと申します。

横槍を入れるようで申し訳ないんですが、回答している皆さんに
「本当に null を返していいの?」という便乗質問です。

[quote]
うるさんの書き込み (2005-10-16 14:21) より:
ResultSet rsをretunで返したいのですが、上手く返せません。
例外処理部分で宣言した変数をretunで返したい時は、
どうすればよろしいのでしょうか?
ResultSet rsを例外処理の外で宣言する方法だと、
初期化の仕方が分からないので、retunで返せません。


ResultSet getDbField(String aFiled, String aTable){
String filed = "";
int i=0;

connectionDb(READ_ONLY); //DBへの接続

StringTokenizer tokenFiled = new StringTokenizer(aFiled,",");

while(tokenFiled.hasMoreTokens()){
//フィールド名の間に,を入れる
if(i != 0){
filed += ",";
}
i++;

filed += tokenFiled.nextToken();
}

try{
PreparedStatement prdStt=db.prepareStatement("SELECT " + filed + " FROM " + aTable);
ResultSet rs = prdStt.executeQuery();
closeDb(); // DBの切断
return rs;
}catch (Exception e){

}
}

[/quote]

もともとこのメソッドで実現したいのは、
  「DBからのSelect結果を返したい」
ということですよね?

私なら、こういったケースでは、
0.例外は例外として、そのまま上位に投げる
(ResultSet getDbField(...) throws SQLException {...})
1.他の方が既に指摘しているように、例外発生したら「null」を返す
2.そもそもResultSetを返すのではなく、その内容をMapやBeanのList、
  もしくはMapやBeanの配列にコピーして返す
  (例外が発生したらnullではなく空(=サイズ0)のListや配列を返す)
3.自分で2.を実装するのは面倒なので、Jakarta Commons あたりで
  使えそうなAPIやクラスを物色する(DBUtils?)
といった方法を思いつきます。
#他の方法、思いつく方いますか?>皆様

このメソッドがどういった使われ方をするのかわからないので、
上記のどの案が最善か(つまり皆さんの回答が「最適解」かどうか)、
私には一概に言えません。

"何が何でもResultSetを返せ"と仕様(試験問題、実習課題)として
決められていて変更できないなら1の方法でしょうが、
そうでないなら(DBアクセスの処理を局所化したいとかなら)、
私だったら2(あるいは3)の方法を使います。
#2.の方法は敷居が高そうですが、java.sqlパッケージのクラスを
#2つ3つ組み合わせれば実現可能です。


なぜなら、うるさんの方法だと、
・メソッドの呼び元で毎回戻り値の null チェックをしないといけなくなり、
 むしろコーディングの手間が増える
・何が原因で null が帰って来るのか(接続に失敗したのか、
 SQLが間違っているのか、切断に失敗したのか)このメソッドの呼び出し元
 で判断できない。(従ってデバッグが大変になるのではないか)
といったデメリットのほうが大きいと考えるからです。

深読みしすぎかもしれませんが、皆さんのご意見はいかがでしょうか。

#これで「ResultSetは一例で、 try{} の中で宣言した変数の値を
#catch{} の中から返す方法が知りたい」だけだったら…。
#う〜ん。

_________________
うる
常連さん
会議室デビュー日: 2005/10/16
投稿数: 41
投稿日時: 2005-10-17 23:43
回答ありがとうございました。

YasTさんの書かれたように、
ResultSet ではない方法で返すというのも、
検討したいと思います。

DBコネクションをクローズしてもResultSetは、
使えてるみたいです。
retunrで返ってきたResultSet rsを使う事ができましたので。
でもこの方法は使わない方が良いのかもしれませね。

ちょま吉
大ベテラン
会議室デビュー日: 2004/08/04
投稿数: 112
投稿日時: 2005-10-17 23:59
ちょま吉です。

私も同感です。
catchしたのであればそのExceptionをthrowすべきと思います。
そしてその検索メソッドを使うビジネスロジックでちゃんとしたエラー処理(メッセージを出す)等を行うべきと考えます。

他の人もそれは考えているのでしょうが、とりあえず目的のResultSetをリターンできるように回答しているのでしょう。
1

スキルアップ/キャリアアップ(JOB@IT)