Подтвердить что ты не робот

Поведение SELECT-запроса с помощью executeUpdate

Я столкнулся с странным поведением при выполнении запроса SELECT с использованием Statement#executeUpdate() по ошибке. Хотя Javadoc четко заявляет, что executeUpdate() throws SQLException, если данный оператор SQL создает объект ResultSet. Но когда я выполняю SELECT * from TABLE_NAME, я не получаю никакого исключения. Вместо этого я получаю возвращаемое значение, которое аналогично значению no. выбранных строк, если нет. меньше или равно 10. Если нет. более 10, возвращаемое значение всегда равно 10.

Connection conn;
Statement stmt;
try {
    conn = getConnection();
    stmt = conn.createStatement();
    int count = stmt.executeUpdate("SELECT * from TABLE_NAME");
    log.info("row count: " + count);
} catch (SQLException e) {
    log.error(e);
    // handle exception
} finally {
    DbUtils.closeQuietly(stmt);
    DbUtils.closeQuietly(conn);
}

Я использую Oracle 10g.

Я что-то упустил или это зависит от драйверов, чтобы определить их собственное поведение?

4b9b3361

Ответ 1

Такое поведение определенно противоречит API Statement.executeUpdate. Что интересно, java.sql.Driver.jdbcCompliant API говорит: "Драйвер может сообщать только истину здесь, если он проходит тесты соответствия JDBC". Я тестировал oracle.jdbc.OracleDriver.jdbcCompliant - он возвращает true. Я также тестировал com.mysql.jdbc.Driver.jdbcCompliant - он возвращает false. Но в той же ситуации, что и вы описываете, он бросает

Exception in thread "main" java.sql.SQLException: Can not issue SELECT via executeUpdate().

Кажется, что драйверы JDBC непредсказуемы.

Ответ 2

В соответствии со спецификациями метод Statement.executeUpdate() возвращает the row count for SQL Data Manipulation Language (DML).

UPD: я попытался сделать предположение о возвращаемом результате (который всегда & lt; = 10). Похоже, что реализация оператора оракула возвращает здесь такой номер, называемый premature batch count (согласно классу декомпилированных источников OraclePreparedStatement). Это как-то связано с обновлениями заявления. Может быть, это значение равно 10 по умолчанию.

UPD-2: В соответствии с этим: Расширения производительности: The premature batch flush count is summed to the return value of the next executeUpdate() or sendBatch() method.

Ответ 3

Запрос, который вы используете, не создает ResultSet, но, очевидно, влияет на строки. Вот почему вы не получаете SQLException, а количество отрицательных строк. Тайна заключается в том, почему она не выходит за пределы 10. Возможно, это специфическая реализация драйвера JDBC Oracle.

Ответ 4

Ваш запрос sql должен извлекать все строки из table_name. Таким образом, вы можете использовать метод execute() вместо метода executeUpdate(). Потому что более поздний метод обычно используется, когда ваша задача связана с базой данных, манипулирующей языком, например, с запросом обновления.

Ответ 5

использование

int count = stmt.executeQuery( "SELECT * from TABLE_NAME" );

вместо

int count = stmt.executeUpdate( "SELECT * from TABLE_NAME" );

для получения итогового нет. строк.

Ответ 6

Для общего случая (выберите или обновите):

    Statement st = conn.createStatement();
    st.execute(sql);