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)

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

Ответ 1

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

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

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

Ответ 2

Тип 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);
        }

Ответ 3

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

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

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

Ответ 4

Хотя этот вопрос старый, ответы не стареют, столкнулись с подобной проблемой сегодня, вот как я подошел к ней, так как здесь Это функциональность, предоставляемая драйвером Java JDBC, и база данных 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() обратное перемещение операции указателя

Ответ 5

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

rs.beforeFirst();

потому что это будет прокручиваться назад.

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

Ответ 6

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

Ответ 7

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

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

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

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

Ответ 8

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

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