Java - CallableStatement executeQuery發生陳述式沒有傳回 Result set

無意中在利用Java執行store procedure要傳回ResultSet的結果時,發生"陳述式沒有傳回 Result

set"的錯誤訊息。後來google了一下發現原來是在我們的store procedure內如果有做類似紀錄

的更動,如建立一個虛擬table,插入新的資料。因此在這邊可以透過SQL語法設定來避免。

Java程式執行的錯誤訊息如下:



欲呼叫的Store Procedure如下:
  1. IF OBJECT_ID ( 'dbo.sp_income_record3', 'P' ) IS NOT NULL
  2. DROP PROCEDURE dbo.sp_income_record3;
  3. GO
  4.  
  5. Create Proc sp_income_record3
  6. @PARAM1 VARCHAR(10),
  7. @PARAM2 VARCHAR(10)
  8. WITH RECOMPILE
  9. As
  10. create table #tmp_no (
  11. no varchar(16) not null,
  12. seq varchar(4) not null
  13. primary key (no,seq)
  14. );
  15. declare @st varchar(100);
  16.  
  17. set @st =
  18. '
  19. insert into #tmp_no(no,seq) values ('+@PARAM1+', '+@PARAM2+')
  20. ';
  21. exec (@st); --執行@st
  22. select no + seq as new_no from #tmp_no
  23. Go

很簡單的一個例子,目的只是將兩個參數傳進去,並塞入到虛擬的table內,之後再針對該

table做查詢的動作來得到一個查詢結果!!

Java 程式碼如下:
  1. Connection m_conn = null;
  2. CallableStatement cs = null;
  3. String driver = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
  4. String url = "jdbc:sqlserver://localhost:1433;DatabaseName=Homework";
  5. String user = "sa";
  6. String password = "gba123";
  7. String sql = "{Call sp_income_record3 ('103001', '1')}";
  8. try{
  9. Class.forName(driver);
  10. m_conn = DriverManager.getConnection(url, user, password);
  11. cs = m_conn.prepareCall(sql);
  12. ResultSet rs = cs.executeQuery();
  13. while(rs.next()){
  14. System.out.println(rs.getString("new_no"));
  15. }
  16. }catch(Exception e){
  17. e.printStackTrace();
  18. }finally{
  19. try {
  20. if(m_conn != null)
  21. m_conn.close();
  22. } catch (SQLException e) {
  23. // TODO Auto-generated catch block
  24. e.printStackTrace();
  25. }
  26. }

很簡單的一支測試程式,呼叫store procedure並帶入相關的參數,之後執行executeQuery取

得一ResultSet要得到查詢的結果,並印出來!

執行後的結果如上圖所示,出現錯誤!!

後來google了一下發現蠻多人有這個問題,輾轉至微軟官方網站有提到SET NOCOUNT

的設定及下面這段說明

Stops the message that shows the count of the number of rows affected by a Transact-SQL statement or stored procedure from being returned as part of the result set.

因此當您在執行store procedure時,如果有上述相關的情形,請在執行sp時需加上

SET NOCOUNT ON,如下

  1. ...
  2. WITH RECOMPILE
  3. AS
  4. SET NOCOUNT ON
  5. ...

如此一來,就可以正常的取得ResultSet結果.

留言

張貼留言