ResultSet виняток - перед початком набору результатів


78

У мене проблеми з отриманням даних від ResultSetоб’єкта. Ось мій код:

    String sql = "SELECT type FROM node WHERE nid = ?";
    PreparedStatement prep = conn.prepareStatement(sql);
    int meetNID = Integer.parseInt(node.get(BoutField.field_meet_nid));
    prep.setInt(1, meetNID);

    ResultSet result = prep.executeQuery();
    result.beforeFirst();
    String foundType = result.getString(1);

    if (! foundType.equals("meet")) {
        throw new IllegalArgumentException(String.format("Node %d must be of type 'meet', but was %s", meetNID, foundType));
    }

Трасування помилки:

Exception in thread "main" java.sql.SQLException: Before start of result set
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1072)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:986)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:981)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:926)
    at com.mysql.jdbc.ResultSetImpl.checkRowPos(ResultSetImpl.java:841)
    at com.mysql.jdbc.ResultSetImpl.getStringInternal(ResultSetImpl.java:5656)
    at com.mysql.jdbc.ResultSetImpl.getString(ResultSetImpl.java:5576)
    at nth.cumf3.nodeImport.Validator.validate(Validator.java:43)
    at nth.cumf3.nodeImport.Main.main(Main.java:38)

Що я тут роблю не так?

Відповіді:


167

В основному ви розміщуєте курсор перед першим рядком, а потім запитуєте дані. Вам потрібно перемістити курсор у перший рядок.

 result.next();
 String foundType = result.getString(1);

Зазвичай це роблять у операторі if або циклі.

if(result.next()){
   foundType = result.getString(1);
}

Чи безпечно використовувати result.next () або result.first () під час виконання простого запиту COUNT, оскільки він ніколи не повинен бути нульовим, і колись він матиме лише 1 результат.
jDub9,

2
Можливо, використовувати result.first()для цього сценарію.
Вінсент Рамдхані

Виявляється, спочатку повертається булевий не перший результат, як я спочатку думав. Здається, я не міг зробити це в 1 рядку, як це намагався зробити, і мені довелося використовувати вищезазначену логіку для виконання запиту, потім наступного, потім getInt (1). Що ж, добре.
jDub9,

11

Кожна відповідь використовує .next()або використовує, .beforeFirst()а потім .next(). Але чому б і не цього:

result.first();

Отже, Ви просто встановите вказівник на перший запис і перейдете звідти. Він доступний з версії 1.2, і я просто хотів згадати про це для тих, у кого ResultSetіснує один конкретний запис.


Використання first()вимагає прокручуваного набору результатів. API вимагає видавати виняток, якщо набір результатів є TYPE_FORWARD_ONLY.
Марк Роттевель,

6

Вам потрібно зробити result.next (), перш ніж отримати доступ до результату. Це дуже поширена ідіома

ResultSet rs = stmt.executeQuery();
while (rs.next())
{
   int foo = rs.getInt(1);
   ...
}

3

Вам потрібно зателефонувати, next()перш ніж ви зможете почати читати значення з першого рядка. beforeFirstставить курсор перед першим рядком, тому немає даних для читання.


2

Краще, якщо ви створите клас, який має всі методи запиту, включно, в іншому пакеті, тому замість того, щоб вводити весь процес у кожному класі, ви просто викликаєте метод із цього класу.


1

Вам потрібно перемістити вказівник на перший рядок, перш ніж запитувати дані:

result.beforeFirst();
result.next();
String foundType = result.getString(1);
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.