PreparedStatement:查询还是更新?
PreparedStatement: Query, or Update?
给定 java.sql.PreparedStatement 的实例 stmt,我可以执行 stmt.executeQuery()
,如果我的 SQL 语句是 SELECT,那么 returns 结果,或者我可以为 INSERT 或 UPDATE 做 stmt.executeUpdate()
。
现在,提出我不知道的情况,正在执行哪种 SQL 语句?我希望有一些方便的东西,比如 stmt.hasResultSet()
,但那不存在。解析 SQL 语句似乎不是一个好的选择。
你总是可以做一个 executeQuery()
但传递给一个结果集,比如:
ResultSet rs = ps.executeQuery();
获得结果集后,您可以获取其元数据:
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());
}
}
JDBC API 提供 PreparedStatement.execute()
method (and Statement.execute(String)
) 正是为此目的:
Executes the SQL statement in this PreparedStatement
object, which
may be any kind of SQL statement. Some prepared statements return
multiple results; the execute
method handles these complex
statements as well as the simpler form of statements handled by the
methods executeQuery
and executeUpdate
.
The execute
method returns a boolean
to indicate the form of the
first result. You must call either the method getResultSet
or
getUpdateCount
to retrieve the result; you must call
getMoreResults
to move to any subsequent result(s).
Returns:
true
if the first result is a ResultSet
object; false
if
the first result is an update count or there is no result
因此,要执行未知语句,您需要执行以下操作:
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 服务器)可以生成多个结果集和多个更新计数,而这将处理所有这些。
给定 java.sql.PreparedStatement 的实例 stmt,我可以执行 stmt.executeQuery()
,如果我的 SQL 语句是 SELECT,那么 returns 结果,或者我可以为 INSERT 或 UPDATE 做 stmt.executeUpdate()
。
现在,提出我不知道的情况,正在执行哪种 SQL 语句?我希望有一些方便的东西,比如 stmt.hasResultSet()
,但那不存在。解析 SQL 语句似乎不是一个好的选择。
你总是可以做一个 executeQuery()
但传递给一个结果集,比如:
ResultSet rs = ps.executeQuery();
获得结果集后,您可以获取其元数据:
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());
}
}
JDBC API 提供 PreparedStatement.execute()
method (and Statement.execute(String)
) 正是为此目的:
Executes the SQL statement in this
PreparedStatement
object, which may be any kind of SQL statement. Some prepared statements return multiple results; theexecute
method handles these complex statements as well as the simpler form of statements handled by the methodsexecuteQuery
andexecuteUpdate
.The
execute
method returns aboolean
to indicate the form of the first result. You must call either the methodgetResultSet
orgetUpdateCount
to retrieve the result; you must callgetMoreResults
to move to any subsequent result(s).Returns:
true
if the first result is aResultSet
object;false
if the first result is an update count or there is no result
因此,要执行未知语句,您需要执行以下操作:
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 服务器)可以生成多个结果集和多个更新计数,而这将处理所有这些。