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

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

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

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

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



欲呼叫的Store Procedure如下:
IF OBJECT_ID ( 'dbo.sp_income_record3', 'P' ) IS NOT NULL
    DROP PROCEDURE dbo.sp_income_record3;
GO

Create Proc sp_income_record3 
@PARAM1 VARCHAR(10), 
@PARAM2 VARCHAR(10) 
WITH RECOMPILE
As 
  create table #tmp_no (
     no varchar(16) not null,
     seq  varchar(4) not null
     primary key (no,seq) 
  );
  declare @st varchar(100);

set @st =
 '
 insert into #tmp_no(no,seq) values ('+@PARAM1+', '+@PARAM2+')
 ';
    
exec (@st); --執行@st
  select no + seq as new_no from #tmp_no
Go

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

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

Java 程式碼如下:
  Connection m_conn = null;
  CallableStatement cs = null;
  String driver = "com.microsoft.sqlserver.jdbc.SQLServerDriver";
  String url = "jdbc:sqlserver://localhost:1433;DatabaseName=Homework";
  String user = "sa";
  String password = "gba123";
  String sql = "{Call sp_income_record3 ('103001', '1')}";
  
  try{
     Class.forName(driver);
     m_conn = DriverManager.getConnection(url, user, password);
   
     cs = m_conn.prepareCall(sql);
   
     ResultSet rs  = cs.executeQuery();
     while(rs.next()){
        System.out.println(rs.getString("new_no"));
     }
  }catch(Exception e){
   e.printStackTrace();
  }finally{
   try {
    if(m_conn != null)
     m_conn.close();
   } catch (SQLException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
   }
  }

很簡單的一支測試程式,呼叫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,如下

...
WITH RECOMPILE
AS
SET NOCOUNT ON
...

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

留言

張貼留言