Nano Hash - криптовалюты, майнинг, программирование

Java SQL: Statement.hasResultSet()?

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

  • В MySQL PreparedStatement.getResultSet() вернет null.
  • В SQLite PreparedStatement.getResultSet() вызовет java.sql.SQLException: no ResultSet available.

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

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

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

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


  • любая конкретная причина, по которой вы хотите вернуть значение null для запроса DELETE, потому что запрос DELETE всегда будет возвращать значение null в качестве набора результатов 08.01.2013
  • у меня есть метод, который выполняет все запросы, и с DELETE в MySQL он возвращает null, как вы сказали, но в SQLite он выдает исключение. 08.01.2013
  • Я использую этот драйвер JDBC между bitbucket.org/xerial/sqlite-jdbc 08.01.2013
  • @BhavikShah: это верно только для двух упомянутых СУБД. Другие СУБД действительно могут что-то вернуть из оператора DELETE, например. delete ... returning ...) 08.01.2013
  • Ни один оператор не имеет набора результатов, пока вы его не выполните. Так что исполняй. 13.01.2013

Ответы:


1

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

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

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

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

Больше нет результатов, только если getMoreResults() возвращает false и 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();
}
19.01.2013

2

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

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

08.01.2013
  • У меня сложилось впечатление, что вы все равно должны использовать execute() даже для таких вещей, как SELECT, прежде чем использовать getResultSet()? Потому что для SELECT кажется, что все работает нормально, если я делаю оба... 08.01.2013
  • Даже если я ошибаюсь в предыдущем комментарии, мой вопрос остается; как мне программно узнать, использовать ли execute() или getResultSet()? 08.01.2013
  • @Dreen Используйте executeQuery для запросов, которые производят 1 и только 1 набор результатов, executeUpdate для запросов, которые только изменяют (и создают один счетчик обновлений) и execute для всех остальных вещей (существование и количество обновлений и/или наборов результатов либо неизвестны заранее или более 1. 08.01.2013
  • поэтому я принял это, потому что пришел к выводу, что нет способа определить это программно. вместо этого я собираюсь проверить первое слово в строке запроса и использовать соответствующий метод, как подробно описано @MarkRotteveel 08.01.2013
  • @Dreen Есть способ определить это программно, но сейчас у меня нет времени набирать полный ответ. 08.01.2013
  • @MarkRotteveel, в любом случае спасибо за вашу помощь и помощь всем остальным, и если вы найдете время, я поменяю мой принятый ответ на ваш. 08.01.2013
  • Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

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

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

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

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..