Java SQL: Statement.hasResultSet()?

Мое приложение использует MySQL на одной платформе и SQLite на другой, поэтому существуют различия, например, при использовании запросов, таких как DELETE FROM USERS:

  • На MySQLPreparedStatement.getResultSet() вернусь null,
  • На SQLite, PreparedStatement.getResultSet() будет бросать java.sql.SQLException: no ResultSet available,

Это может быть, а может и не быть ошибкой в ​​реализации SQLite (я думаю, что она должна возвращаться null), но я должен как-то с этим справиться.

Я мог бы использовать try { ... } catch (SQLException e) { ... } и если сообщение об исключении "no ResultSet available", просто верните ноль вручную. Это не похоже на правильный способ сделать это все же.

Я мог бы поставить, если это проверяет, какой драйвер JDBC используется, и реагировать соответствующим образом, но опять же, это не похоже на хорошее решение проблемы.

То, что я действительно хотел бы, это либо метод, как .hasResultSet() который возвращает boolean ИЛИ способ получить команду SQL (SELECT, UPDATE, INSERT и т. д.) из заявления, которое было выполнено. Я не могу найти ни один из двух в SQL API, хотя.

2 ответа

Решение

При выполнении запроса, который возвращает неизвестное количество результатов, необходимо использовать execute(), Этот метод возвращает boolean с указанием типа результата:

  • true: результат ResultSet
  • false: результат - количество обновлений

Если результат true тогда вы используете getResultSet() чтобы получить ResultSet, иначе getUpdateCount() чтобы получить количество обновлений. Если счетчик обновлений -1 значит, больше нет результатов. Обратите внимание, что количество обновлений также будет -1 когда текущий результат ResultSet, Также хорошо знать, что getResultSet() должен возвращать ноль, если результатов больше нет или если результатом является счетчик обновлений, поэтому поведение SQL Lite для выдачи исключения кажется неправильным.

Теперь, если вы хотите получить больше результатов, вы звоните getMoreResults() (или его брат принимает int параметр). boolean Возвращаемое значение этого метода имеет то же значение, что и значение execute(), так false не означает, что больше нет результатов!

Больше нет результатов, если getMoreResults() возвращает ложь и getUpdateCount() возвращается -1 (как также задокументировано в Javadoc)

По сути это означает, что если вы хотите правильно обработать все результаты, вам нужно сделать что-то вроде:

PreparedStatement pstmt = connection.prepareStatement(...);
// ...
boolean result = pstmt.execute();
while(true)
    if (result) {
        ResultSet rs = pstmt.getResultSet();
        // Do something with resultset ...
    } else {
        int updateCount = pstmt.getUpdateCount();
        if (updateCount == -1) {
            // no more results
            break;
        }
        // Do something with update count ...
    }
    result = pstmt.getMoreResults();
}

Проблема в том, что вы используете недопустимый метод для выполнения операции удаления. Вместо того, чтобы использовать getResultSet ты должен использовать Statement#execute(String)

ИМХО Исключение в реализации SQLite является более допустимым, чем ноль для MySQL. Как delete не возвращать набор, но скалярное значение удаленных строк.

Другие вопросы по тегам