13

我在错误地执行 SELECT 查询时遇到了一个奇怪的行为Statement#executeUpdate()。而 Javadoc 明确指出,executeUpdate() throws SQLException如果给定的 SQL 语句产生一个 ResultSet 对象。但是当我执行时SELECT * from TABLE_NAME,我没有得到任何异常。相反,我得到的返回值与否相同。选择的行数,如果没有。小于或等于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

我在这里遗漏了什么,还是由司机来定义自己的行为?

4

6 回答 6

4

Statement.executeUpdate这种行为与API完全矛盾。有趣的是, java.sql.Driver.jdbcCompliantAPI 说“如果驱动程序通过了 JDBC 合规性测试,它可能只会在此处报告 true”。我测试过oracle.jdbc.OracleDriver.jdbcCompliant-它返回true。我也测试过com.mysql.jdbc.Driver.jdbcCompliant- 它返回错误。但是在与您描述的情况相同的情况下,它会抛出

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

看来 JDBC 驱动程序是不可预测的。

于 2012-12-19T07:23:09.187 回答
3

按规格Statement.executeUpdate()方法返回the row count for SQL Data Manipulation Language (DML)

UPD:我试图对返回的结果做出假设(总是 <= 10)。看来,oracle 语句的实现在这里返回了一些这样的调用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.

于 2012-12-19T07:04:43.103 回答
2

您正在使用的查询不会产生 ResultSet 但显然会影响 Rows 。这就是为什么您没有得到 SQLException 而是计算受影响的行数的原因。奥秘在于它为什么不超过 10。可能是 Oracle JDBC Driver Implementation Specific。

于 2012-12-19T07:01:36.707 回答
1

您的 sql 查询是从 table_name 中检索所有行。因此,您可以使用execute()方法而不是executeUpdate()方法。因为后面的方法通常在您的任务是相关数据库操作语言(如更新查询)时使用。

于 2012-12-19T07:05:41.663 回答
1

采用

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

代替

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

获得总数。的行

于 2012-12-28T14:09:53.723 回答
0

对于一般情况(选择或更新):

    Statement st = conn.createStatement();
    st.execute(sql);
于 2013-08-13T11:01:12.083 回答