JavaストアドプロシージャでResultSetが返ってこない

このQ&Aのポイント
  • Java+ストアドプロシージャでResultSetが返ってきません
  • idを送りその値を元にSELECTを行い、もしそのidに該当するデータがなければ空行を追加し、その行を返すストアドプロシージャに接続したいのですが、空行追加の際、空行追加後にその行が返ってきません。
  • @count=0の場合、SELECT文を実行しているのか調べたくて戻り値を設定し、どの段階まで動いているのか調べようとしたのですが戻り値を設定すると「インデックス 2 は範囲外です。」と出てしまいます。色々なページを探してみたのですが、それらしい文章を見つけることができなかった為、先輩方ご教授願います。
回答を見る
  • ベストアンサー

Java+ストアドプロシージャでResultSetが返ってきません

idを送りその値を元にSELECTを行い、もしそのidに該当するデータがなければ空行を追加し、その行を返すストアドプロシージャに接続したいのですが、空行追加の際、空行追加後にその行が返ってきません。(戻ってきた際、ResultSetを取得しても値がnullのままです) @count=0の場合、SELECT文を実行しているのか調べたくて戻り値を設定し、どの段階まで動いているのか調べようとしたのですが戻り値を設定すると「インデックス 2 は範囲外です。」と出てしまいます。 色々なページを探してみたのですが、それらしい文章を見つけることができなかった為、先輩方ご教授願います。 Javaサイドのソース CallableStatement pstmt = db.prepareCall("{ call dbo.EmpLoad (?)}"); pstmt.setString(1,id); pstmt.execute(); rs=pstmt.getResultSet(); if(rs!=null){//ここでnullなのでIFの中に入らない   if(rs.next()){ EmpName=rs.getString("EmployeeName"); PostNO=rs.getInt("PostNO"); PositionName=rs.getString("PositionName"); Address=rs.getString("Address"); Tel=rs.getString("Tel"); Birthday=rs.getDate("Birthday"); WorkSituationNO=rs.getInt("WorkSituationNO"); InCompanyDate=rs.getDate("InCompanyDate"); OutCompanyDate=rs.getDate("OutCompanyDate"); Zip=rs.getString("Zip"); strMessage=""; } } else{ strMessage=":"+rs.; } ストアドプロシージャのソース ALTER PROCEDURE [dbo].[EmpLoad](@empNO int) AS BEGIN DECLARE @count int=(SELECT COUNT(*) FROM EmployeeTable where EmployeeTable.EmployeeNO=@empNO); IF @count=0 BEGIN INSERT INTO EmployeeTable(EmployeeName) values(NULL); INSERT INTO DetailsEmployeeTable(EmployeeNO) SELECT MAX(EmployeeNO) FROM EmployeeTable; SELECT * FROM EmployeeTable,DetailsEmployeeTable where EmployeeTable.EmployeeNO =(SELECT MAX(EmployeeNO)FROM EmployeeTable) AND EmployeeTable.EmployeeNO=DetailsEmployeeTable.EmployeeNO; END IF @count=1 BEGIN SELECT * FROM EmployeeTable,DetailsEmployeeTable where EmployeeTable.EmployeeNO=@empNO AND EmployeeTable.EmployeeNO=DetailsEmployeeTable.EmployeeNO; END END

質問者が選んだベストアンサー

  • ベストアンサー
  • jamshid6
  • ベストアンサー率88% (591/669)
回答No.2

SQL Server 2008ですか。。 SQL Serverでは、すべてのステートメントについて「xx行更新しました」というメッセージが返されます。 呼び出し元ではそれぞれを戻りと認識してしまうので、@count=0のときは、最初の2つ(INSERT)のResultSetはNULLです。 これらのメッセージを抑止するために、ストアドでは「SET NOCOUNT ON」と先頭に切るのが一般的です。 ただ、Javaで試したわけでないので、もし効かなければ、ResultSetがNULLでなくなるまでgetMoreResultsを繰り返す必要があります。

lovedrop10
質問者

お礼

ありがとうございます!解決しましたっ そういうことだったんですね・・・。きちんと結果も得ることができて、自分の無知さを思い知りました^^; 本当にありがとうございました。

その他の回答 (2)

  • bleis
  • ベストアンサー率68% (11/16)
回答No.3

そういうことではなくて、execute の戻り値として false が返ってきているんじゃないかな?ということです。 @count が 0 だと、INSERTが実行されるため、execute の戻り値として false が返ってきてもおかしくはありませんし。 APIリファレンスには、 「最初の結果が ResultSet オブジェクトの場合は true。更新カウントであるか、または結果がない場合は false」 とありますので、execute の戻り値のチェックは必須ですよ。

  • bleis
  • ベストアンサー率68% (11/16)
回答No.1

まずはAPIリファレンスを読みましょう。 http://www.j2ee.me/javase/ja/6/docs/ja/api/java/sql/PreparedStatement.html#execute()

lovedrop10
質問者

補足

えっと、恐らくなのですが execute()ではなくexecuteQuery()を使え ということでしょうか? はじめはexecuteQueryを使用していたのですが、こちらですとexecuteQueryを実行してすぐにエラーログが出てしまい、原因を究明することができませんでしたので、一度executeしてからgetResultSetをするという手間を踏んでいるのです。 判りづらいソースで申し訳ありません・・・

関連するQ&A

  • Resultsetについて困っています。

    Struts DBからデータを取得し、名称をコンボボックスに設定しようとしています。具体的には、一つの商品に登録してあるサイズと色をコンボボックスで表示しようとしています。 取得した値をbeanにセットしようとしているのですが、取得する値が複数ある項目が、複数ある場合について質問させて頂いております。 下記のように”SELECTDETAIL”でDBから1行 の項目の値を取得しています。列項目は"ID"と"NAME"です。 この先、"SIZE"と"color"の値をbeanにセットしようとしているます。"SELECTDETAIL"で取得するのは1行で、サイズと色は複数行なのでこの二つは"public List<Product>・・・"でbeanにセットしようと思っています。しかし、サイズと色の取得する行数は異なるので、それぞれ"public List<Product>・・・"を作った方がいいのでしょうか?お願い致します。 ---ProductはActionFormです--- private static final String SELECTDETAIL = "select * from goods_info where ID=?"; public Product getProduct(int ID) throws Exception{ Connection con = source.getConnection(); PreparedStatement pStmt = null; ResultSet rs = null; try{ pStmt = con.prepareStatement(SELECTDETAIL); pStmt.setInt(1,ID); rs = pStmt.executeQuery(); if(rs.next()){ return getProduct(rs); } }catch(SQLException ex){ throw ex; }finally{ if(rs != null){ rs.close(); } pStmt.close(); con.close(); } return null; } ---ActionFormにセット--- private Product getProduct(ResultSet rs) throws SQLException { Product pro = new Product(); pro.setGoods_info_id(rs.getInt("ID")); pro.setGoods_name(rs.getString("NAME")); return pro; }

  • MySQLのストアドプロシージャについて

    MySQL5.6のストアドプロシージャが返すSELECT結果のフェッチ方法について教えてください。 delimiter $ create procedure sample_proc() begin select * from TEST_TBL; end$ の様なストアドプロシージャがあり、これを他のストアドプロシージャから呼び出して、 ループしながらフェッチしたいのですが、どうすればよいでしょうか。

  • MYSQL ストアドプロシージャの記述方法

    MYSQLのストアドプロシージャについて分からないことがあり質問させて頂きます。 SQLのwhere句の部分を引数によって条件分で変更させたいと考えています。そこでORACLEの場合は変数にいれて最後に明示的にSQLを発行して いたので可能だったのですが、MYSQLの場合はどういった記述になる のかわかりません。やりたいことは下記のような感じです。 ORACLEの場合は procedure prctest(pc out refcur,a in varchar2,b in varchar2) is sqldata varchar2(1000); whereinfo varchar2(1000); begin sqldata := 'select ID , NAME from testTbl '; if (a IS NOT NULL) then   whereinfo := whereinfo || ' acol = a ' ; end if; if (b IS NOT NULL) then   if (whereinfo IS NOT NULL) then  whereinfo := whereinfo || ' and ';   end if;   whereinfo := whereinfo || ' acol = b ' ; end if; if (whereinfo IS NOT NULL) then  sqldata := sqldata || ' where ' || whereinfo ; end if; open pc for sqldata; (ここでSQLが入ったSQLを発行) end prctest; (抜粋) ストアドをあまり使用したことがなく良い説明ではないかも しれませんが、アドバイスの方頂けたらと思います。 よろしくお願いします。

  • ストアドプロシージャについて

    お世話になります。 SQLServseのストアドプロシージャで、あるテーブルのテストデータを100件ほど作成したいと思っています。 しかし、プロシージャを実行すると「プライマリキーが重複しています」とエラーが出ます。 テーブル内にはすでにCODE='0001'と'0101'の2件が存在します。そのため挿入開始コードは'0002'としたのですが・・・。まだ同じエラーが発生します。 テーブル名:MST_USER  CODE char(4) ←キー  KBN  char(2)  NAME varchar(40)  PASS varchar(10) 作成したプロシージャ CREATE PROCEDURE dbo.test_update_USER AS declare @count int declare @kbn int set @count = 2 set @kbn = 0 while 1 = 1 begin update MST_USER set CODE = right('0000' + ltrim(str@count)), 4), KBN = right('00' + ltrim(str(@kbn)), 2), NAME = 'test' + ltrim(str(@count)), PASS = 'test' + ltrim(str(@count)) set @count = @count + 1 if (@count > 100) break if (@kbn > 3) set @kbn = 0 else set @kbn = @kbn + 1 end GO 何か間違えているのか自分ではわからなくなっている状態です。 どなたかご指摘いただけると幸いです。

  • ストアドプロシージャが作成されない

    ●質問の主旨 phpMyAdminのMySQLで ストアドプロシージャの動作確認をしています。 試しに、 delimiter // create procedure pr30() begin select * from tb; select * from tb1l; select * from tb1; end // delimiter ; というプロシージャを作成して、 実行を押しても、画面が全く変化しません。 エラーの表示さえされません。 (もちろんデータベーステーブルのtb、tb1l、tb1が 存在することは確認済みです) また、作成している最中に、 命令文が勝手に消えることもあります。 普通に select * from tb; と、書いていても消えることはないのですが…。 この現象や対策についてご存知の方がいらっしゃいましたら、 アドバイスをお願いします。 ●環境 windows8 xammp1.8.1 phpMyAdmin3.5.2.2 MySQL5.5.27

    • ベストアンサー
    • MySQL
  • ストアドファンクション⇒プロシージャ呼出し失敗する

    参考の通りに、ストアドプロシージャ作成SQL文を発行し、 コマンドライン上からは、以下の通りの結果1となり、 レコードがinsertされます。 <結果1> mysql> call logger('ほげ', 'ホゲ'); Query OK, 1 row affected (0.01 sec) mysql> select * from PROCEDURE_LOG; +--------+--------+---------------------+ | NAME | QUERY | EXECUTE_DATE | +--------+--------+---------------------+ | ほげ | ホゲ | 2014-03-26 10:41:26 | +--------+--------+---------------------+ 1 row in set (0.00 sec) ですが、testというストアドファンクションから呼び出してみましたが、 以下の結果2の通り、失敗します。 <結果2> mysql> select test(); ERROR 1336 (0A000): Dynamic SQL is not allowed in stored function or trigger <test> BEGIN CALL logger('test','1'); RETURN CONCAT('END'); END 現在動作している環境では、どこでエラーが発生したかがわからず、 ロガーの処理をなんとしても実装したいのですが、 いろいろ試してみても、解決できませんでした。 ご教示のほど、よろしくお願いします。 <参考> http://treeapps.hatenablog.com/entry/20120106/p1 <ストアドプロシージャ作成SQL文(logger)> SET NAMES UTF8; delimiter // -- ログ出力 DROP PROCEDURE IF EXISTS logger// CREATE PROCEDURE logger( IN PROCEDURE_NAME TEXT, IN SQL_TEXT TEXT ) BEGIN DECLARE CNT INT; CREATE TABLE IF NOT EXISTS PROCEDURE_LOG ( NAME VARCHAR(64), QUERY TEXT, EXECUTE_DATE TIMESTAMP, KEY IDX1 (NAME, QUERY(64), EXECUTE_DATE) ) ENGINE=MYISAM DEFAULT CHARSET=UTF8; -- 古いログを削除 SELECT COUNT(*) INTO CNT FROM PROCEDURE_LOG; IF CNT >= 1000 THEN DELETE FROM PROCEDURE_LOG LIMIT 1; END IF; -- テーブルにログを記録 SET @sql = CONCAT('INSERT INTO PROCEDURE_LOG VALUES (', QUOTE(PROCEDURE_NAME), ',', QUOTE(SQL_TEXT), ', null)'); PREPARE stmt FROM @sql; EXECUTE stmt; END // delimiter ;

    • ベストアンサー
    • MySQL
  • ストアドプロシージャにてフェッチから出ない

    Aというテーブルの情報をカーソルにて取得し、 同じくAというテーブルに項目を変えてInsertするという プロシージャを作成しています。 しかし、フェッチしたあとその処理から出ません。 (ちなみにフェッチ後のBEGIN~END内のInsert文を違うテーブルにして実行してみると処理から抜けました) 下記が該当プロシージャです。 CREATE PROCEDURE 販売プロシージャ AS BEGIN --変数宣言 DECLARE @販売NO INT DECLARE @顧客NO INT DECLARE @明細 NVARCHAR(25) DECLARE @受注日 SMALLDATETIME DECLARE @金額 INT DECLARE @ステータス BIT DECLARE @有効フラグ BIT --カーソル宣言 DECLARE 販売カーソル CURSOR FOR SELECT 販売NO, 顧客NO, 明細, 受注日, 金額, ステータス, 有効フラグ FROM 販売 WHERE YEAR(受注日) = YEAR(GETDATE()) AND MONTH(受注日) < MONTH(GETDATE()) --初期化処理 SET NOCOUNT OFF --カーソルOPEN OPEN 販売カーソル FETCH NEXT FROM 販売カーソル INTO @販売NO, @顧客NO, @明細, @受注日, @金額, @ステータス, @有効フラグ WHILE @@FETCH_STATUS = 0 BEGIN INSERT INTO 販売 ( 販売NO, 顧客NO, 明細, 受注日, 金額, ステータス, 有効フラグ, 登録日, 更新日, )VALUES( @販売NO, @顧客NO, @明細, @受注日, @金額, @ステータス, @有効フラグ, GETDATE(), GETDATE(), ) FETCH NEXT FROM 販売カーソル INTO @販売NO, @顧客NO, @明細, @受注日, @金額, @ステータス, @有効フラグ END CLOSE 販売カーソル DEALLOCATE 販売カーソル END 同じテーブルを使用する場合は、このような記述ではできないのでしょうか?

  • ストアドプロシージャについて

    アドバイスを頂けたらと思います。 php   5.1.6 mysql   5.0.22 接続方法 PDO PHPよりストアドプロシージャを実行するとEXCUTEの部分で応答がなくなりMYSQLの SHOW PROCESSLIST を確認するとそのプロセスがSleep になってしまっています。 記述方法が間違っているか、またはどこか設定するのか、参考意見を 頂ければと思います。 PHP側 <?php try { $user = 'sys'; $pass = 'sys'; $dbh = new PDO('mysql:host=localhost;dbname=testDB', $user, $pass); if ($st = $dbh->prepare("CALL Listget()") ){ $st->execute(); while ($row = $st->fetch()) { print_r ($row); } } } catch (PDOException $e) { print 'Error: ' . $e->getMessage(). "\n"; } $dbh = null; ?> ストアド delimiter // CREATE PROCEDURE Listget ( ) BEGIN SELECT id FROM testTbl; END // よろしくお願いします。

    • ベストアンサー
    • PHP
  • ストアドプロシージャ作成時のエラーについて

    お世話になっております。 CREATE PROCEDURE AAA (IN param INT) BEGIN SELECT CD, NAME FROM TBL WHERE TBL_KEY = param; END INTEGER型の引数を渡してVARCHAR型のCD、NAMEを取り出す程度のストアドプロシージャを作成しようとすると 1303 - Can't create a PROCEDURE from within another stored routine. なるエラーが表示されて作成ができません。 このエラーの理由についてコメント頂ければ幸いです。

    • ベストアンサー
    • MySQL
  • MYSQLでストアドプロシージャの引数を二つ

    MYSQL初心者で参考書にかじりついてプログラミングしています。 主にDBの内容をPHPで吐き出させるといった使い方をしています。 SQL文があまりにも長ったらしくなってきたのでストアドプロシージャを使いたいのですが、使っているSQL文が (SELECT * FROM .変数. WHERE .変数. LIKE '.変数.') UNION (SELECT * FROM .変数. WHERE .変数. LIKE '.変数.'); となっており、引数を複数使えないとスッキリさせられない状況です。 ストアドプロシージャで複数の引数を設定することはできないのでしょうか?

    • ベストアンサー
    • MySQL