Поведение 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.
Я что-то упустил или это зависит от драйверов, чтобы определить их собственное поведение?
Ответы
Ответ 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);