Java SQL: Statement.hasResultSet()?

半腔热情 提交于 2019-12-17 14:33:29

问题


My app uses MySQL on one platform and SQLite on another, as such there are differences, such as that when using query like DELETE FROM USERS:

  • On MySQL, PreparedStatement.getResultSet() will return null.
  • On SQLite, PreparedStatement.getResultSet() will throw java.sql.SQLException: no ResultSet available.

This may or may not be a bug in SQLite implementation (I think it is supposed to return null), but I have to deal with this somehow.

I could use a try { ... } catch (SQLException e) { ... } and if the exception message is "no ResultSet available", simply return null manually. This doesn't feel like a right way to do it though.

I could put up an if that makes a check on what JDBC driver is being used and react accordingly, but again, that doesn't feel like a good solution to the problem.

What I would really like is either a method like .hasResultSet() that returns a boolean OR a way to get the SQL command (SELECT, UPDATE, INSERT etc) from a statement that has been executed. I can find neither of the two in SQL API though.


回答1:


When executing a query that returns an unknown amount of results, then you need to use execute(). This method returns a boolean indicating the type of result:

  • true: result is a ResultSet
  • false : result is an update count

If the result is true, then you use getResultSet() to retrieve the ResultSet, otherwise getUpdateCount() to retrieve the update count. If the update count is -1 it means there are no more results. Note that the update count will also be -1 when the current result is a ResultSet. It is also good to know that getResultSet() should return null if there are no more results or if the result is an update count, so the behavior of SQL Lite to throw an exception seems to be wrong.

Now if you want to retrieve more results, you call getMoreResults() (or its brother accepting an int parameter). The boolean return value of this method has the same meaning as that of execute(), so false does not mean there are no more results!

There are only no more results if the getMoreResults() returns false and getUpdateCount() returns -1 (as also documented in the Javadoc)

Essentially this means that if you want to correctly process all results you need to do something like:

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();
}



回答2:


The problem is that you use invalid method to perform delete operation. Instead of using getResultSet you should use Statement#execute(String)

IMHO the Exeption in SQLite implementation is more valid than null for MySQL. As delete do not return the set but a scalar value of delted rows.



来源:https://stackoverflow.com/questions/14213824/java-sql-statement-hasresultset

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!