PreparedStatement:查询还是更新?

Posted

技术标签:

【中文标题】PreparedStatement:查询还是更新?【英文标题】:PreparedStatement: Query, or Update? 【发布时间】:2021-11-18 16:45:42 【问题描述】:

给定 java.sql.PreparedStatement 的实例 stmt,我可以执行 stmt.executeQuery(),如果我的 SQL 语句是 SELECT,则返回结果,或者我可以执行 stmt.executeUpdate() 执行 INSERT 或 UPDATE。

现在,建议案例,我不知道,正在执行什么样的 SQL 语句?我希望有一些方便的东西,比如stmt.hasResultSet(),但那不存在。解析 SQL 语句似乎不是一个好的选择。

【问题讨论】:

还有一个方法execute(),如果第一个结果是ResultSet对象,则返回truefalse如果第一个结果是更新计数或者没有结果. 【参考方案1】:

JDBC API 提供了PreparedStatement.execute() 方法(和Statement.execute(String))正是为此目的:

执行此PreparedStatement 对象中的SQL 语句,它 可以是任何类型的 SQL 语句。一些准备好的语句返回 多个结果; execute 方法处理这些复杂的 陈述以及由处理的陈述的更简单形式 方法executeQueryexecuteUpdate

execute 方法返回一个boolean 来表示 第一个结果。您必须调用方法getResultSetgetUpdateCount 检索结果;你必须打电话 getMoreResults 移动到任何后续结果。

回报:true 如果第一个结果是 ResultSet 对象; false如果 第一个结果是更新计数或没有结果

因此,要执行未知语句,您需要执行以下操作:

try (PreparedStatement pstmt = connection.prepareStatement(unknownStatement)) 
    // set variables ...

    boolean currentResult = pstmt.execute();
    while (true) 
        if (currentResult) 
            try (ResultSet rs = pstmt.getResultSet()) 
                // process result set
            
         else 
            int updateCount = pstmt.getUpdateCount();
            if (updateCount == -1) 
                // no more results
                break;
            
            // do something with update count
        
        currentResult = pstmt.getMoreResults();
    

存在循环是因为某些数据库系统(例如 SQL Server)可以产生多个结果集和多个更新计数,而这将处理所有这些。

【讨论】:

【参考方案2】:

您始终可以使用executeQuery(),但传递给结果集,例如:

ResultSet rs = ps.executeQuery();

获得 ResultSet 后,您可以获取其元数据:

ResultSetMetaData rsmd = rs.getMetaData();

在此元数据中,您可以检查 getColumnCount() 是否为零或更多,这样您甚至可以获取返回的精确列数,以使用循环执行通用解析:

final ResultSetMetaData rsmd = rs.getMetaData();
final int columnCount = rsmd.getColumnCount();

if (columnCount > 0) 
    while (rs.next()) 
        final StringBuilder sb = new StringBuilder();
        
        for (int i = 1 ; i <= columnCount ; i++) 
            sb.append(rs.getString(i));
            if (i < columnCount) 
                sb.append(", ");
            
        
        
        temp.add(sb.toString());
    

【讨论】:

如果语句没有产生结果集,这将失败并抛出异常。

以上是关于PreparedStatement:查询还是更新?的主要内容,如果未能解决你的问题,请参考以下文章

PreparedStatement 更新显示错误 ORA-00927 缺少等号

PreparedStatement.executeUpdate() 不适用于 Oracle

java中PreparedStatement执行带参数的sql语句如何实现模糊查询?

PreparedStatement

IN子句效率中的preparedstatement设置值

执行sql语句为什么?用PreparedStatement要比Statement好用