ResultSet: исключение: тип набора - TYPE_FORWARD_ONLY - почему? - PullRequest
13 голосов
/ 16 июня 2011

У меня очень простой код:

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)

Что вызывает это и как я могу это исправить?

Ответы [ 8 ]

18 голосов
/ 16 июня 2011

Измените свое первое утверждение на это

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

Таким образом, вы можете двигаться вперед и назад, так что меньше беспокойства о

14 голосов
/ 16 июня 2011

Тип TYPE_FORWARD_ONLY означает, что вы можете двигаться только вперед в наборе результатов, но не назад, поэтому вы получаете исключение, когда пытаетесь вернуться назад с помощью beforeFirst().Вместо этого вы можете либо использовать следующую prepareStatement () , которая получает тип набора результатов в качестве параметра, либо сделать:

        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);
        }
7 голосов
/ 16 июня 2011

Это можно сделать только с результирующим набором типа TYPE_SCROLL_SENSITIVE, который определен как «Константа, указывающая тип объекта ResultSet, который можно прокручивать и, как правило, чувствителен к изменениям, сделанным другими».

Вам нужно сделать что-то вроде следующего ...

Statement statement = 
 connection.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
    ResultSet.CONCUR_READ_ONLY);
6 голосов
/ 14 января 2015

Хотя этот вопрос старый, ответы не устарели, я столкнулся с подобной проблемой сегодня, вот как я подошел к нему: здесь Это функциональность, предоставляемая драйвером JDBC Javaи база данных PostgreSQL.В этом случае создается объект Statement с использованием параметров по умолчанию, сгенерированные системой наборы данных могут быть только односторонним движением указателя вперед, а не двухсторонним указателем мобильной записи данных, первым

Оператор stmt = dbConn.createStatement ();Результат rs = stmt.executeQuery (sql); Изменено на Оператор stmt = dbConn.createStatement (ResultSet.TYPE_SCROLL_INSENSITIVE, ResultSet.CONCUR_READ_ONLY);Результат rs = stmt.executeQuery (sql);Сгенерированный в это время rs может использовать rs.first () операцию обратного перемещения указателя

3 голосов
/ 16 июня 2011

Как говорит исключение: Вы не можете прокрутить свой набор результатов в любом другом направлении, кроме перемотки вперед. Поэтому, когда вы перебираете свой результирующий набор, чтобы получить количество строк (я даже не понимаю, зачем вы это делаете), эта строка выдает это исключение:

rs.beforeFirst();

потому что это будет прокрутка назад.

Либо создайте свое утверждение, чтобы вы могли прокрутить его (например, Google), либо удалите счетчик строк. Я бы предложил последнее, поскольку подсчет кажется ненужным.

2 голосов
/ 08 января 2013

Этот вопрос довольно старый. Я считаю, что решение уже было бы найдено. Однако я хотел бы предложить здесь нечто отличное от того, что сделал Адитья.

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

Вместо ResultSet.TYPE_SCROLL_SENSITIVE я бы использовал INSENSITIVE

Проверьте эту ссылку для ссылки

2 голосов
/ 28 мая 2012

java.sql.SQLException: тип набора результатов - TYPE_FORWARD_ONLY

с API JDBC 2.0 пользователь может перемещать курсор вперед или назад.

Ваша ошибка может быть удалена путем создания 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
0 голосов
/ 16 июня 2011

переменная rowCount не обязательна.Вы выполняете две петли на RS.только второй цикл необходим для получения количества строк, которое выполняется этой частью кода:

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