2011-06-16 53 views
10

我有非常簡單的代碼:ResultSet:異常:集合類型是TYPE_FORWARD_ONLY - 爲什麼?

pstat=con.prepareStatement("select typeid from users where username=? and password=?");    
pstat.setString(1, username); 
pstat.setString(2, password); 
rs=pstat.executeQuery(); 
int rowCount=0; 
while(rs.next()) 
{  
    rowCount++;   
} 
rs.beforeFirst(); 
if(rowCount>=1) 
{ 
while(rs.next()) 
{ 
    typeID=rs.getInt(1); 
} 

但是,當執行此代碼我得到...

java.sql.SQLException: Result set type is TYPE_FORWARD_ONLY 
at sun.jdbc.odbc.JdbcOdbcResultSet.beforeFirst(Unknown Source) 
at server.ClientImpl.login(ClientImpl.java:57) 
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) 
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) 
at java.lang.reflect.Method.invoke(Unknown Source) 
at sun.rmi.server.UnicastServerRef.dispatch(Unknown Source) 
at sun.rmi.transport.Transport$1.run(Unknown Source) 
at java.security.AccessController.doPrivileged(Native Method) 
at sun.rmi.transport.Transport.serviceCall(Unknown Source) 
at sun.rmi.transport.tcp.TCPTransport.handleMessages(Unknown Source) 
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run0(Unknown Source) 
at sun.rmi.transport.tcp.TCPTransport$ConnectionHandler.run(Unknown Source) 
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(Unknown Source) 
at java.util.concurrent.ThreadPoolExecutor$Worker.run(Unknown Source) 
at java.lang.Thread.run(Unknown Source) 

是什麼原因造成這一點,我怎麼能解決這個問題?

回答

13

類型TYPE_FORWARD_ONLY意味着你只能向前的結果集,而不是落後,所以當您嘗試與beforeFirst()回去得到一個異常。相反,你可以使用以下prepareStatement(),接收ResultSet類型作爲參數,或做:

 pstat=con.prepareStatement("select typeid from users where username=? and password=?");    
     pstat.setString(1, username); 
     pstat.setString(2, password); 
     rs=pstat.executeQuery(); 
     int rowCount=0; 

     while(rs.next()) 
     { 
      rowCount++; 
      typeID=rs.getInt(1); 
     } 
+0

我正打算輸入那個。幹得好,@MByD – jpm 2011-06-16 06:11:52

+0

@jpm - 非常感謝! :) – MByD 2011-06-16 06:18:30

3

像異常說:你不能滾動你的結果比前鋒任何其它方向設置。所以,當你遍歷結果集,以獲得行數(我甚至不明白你爲什麼這樣做),那麼該行會拋出該異常:

rs.beforeFirst(); 

,因爲這會向後滾動。

要麼創建您的語句,以便您可以滾動它(例如谷歌)或刪除行計數。我建議後者,因爲計數似乎沒有必要。

16

更改您的第一條語句這個

pstat=con.prepareStatement("select typeid from users where username=? and password=?", 
          ResultSet.TYPE_SCROLL_SENSITIVE, 
         ResultSet.CONCUR_UPDATABLE); 

這樣你就可以前進,後退,東西,所以少操心

6

你只能用一個結果是類型TYPE_SCROLL_SENSITIVE的做到這一點,其定義爲「該常數指示可滾動的ResultSet對象的類型,並且通常對其他人所做的更改敏感。」

你需要做類似下面的...

Statement statement = 
connection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, 
    ResultSet.CONCUR_READ_ONLY); 
0

根據rowCount變量是沒有必要的。你正在rs上執行兩個循環。僅第二環路是必要的以獲得其通過的這部分代碼進行行數:

while (rs.next()){ 
typeID=rs.getInt(1); //typeID is the number of rows in the ResultSet 
} 
2

java.sql.SQLException中:結果集類型是TYPE_FORWARD_ONLY

用JDBC 2.0 API,用戶可以靈活地向前或向後移動光標。

你的錯誤可以通過創建statemnt被刪除如下

Statement st = conn.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_READ_ONLY); 

此外,一個更好的方法來計算行數將

rs=pstat.executeQuery();    //execute the query 
rs.last();        //move the cursor to the last row 
int numberOfRows = rs.getRow();   //get the number of rows 
rs.beforeFirst();      //back to initial state 
2

這個問題是很老。我相信這個解決方案已經找到了。不過,我想在這裏建議一些與Aditya不同的東西。

pstat=con.prepareStatement("select typeid from users where username=? and password=?", 
           ResultSet.TYPE_SCROLL_INSENSITIVE, 
          ResultSet.CONCUR_UPDATABLE); 

相反ResultSet.TYPE_SCROLL_SENSITIVE的,我會用不敏感

Check this link for refernce

4

儘管這個問題的時候,答案沒有老化,今天遇到了類似的問題,這是我走近它,如here 這是由Java JDBC驅動程序和PostgreSQL數據庫提供的功能。 這種情況下使用默認參數創建Statement對象時,系統生成的數據集只能是一個方向前進的指針,而不是雙向移動數據記錄指針,前者

聲明語句= dbConn.createStatement();
結果rs = stmt.executeQuery(sql);

更改爲
語句stmt = dbConn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,爲ResultSet.CONCUR_READ_ONLY);
結果rs = stmt.executeQuery(sql);

此時生成rs可以使用rs.first()反向移動指針操作

相關問題