问题
这个问题在这里已有答案:
- 如何获取PreparedStatement的SQL? 11个答案
在我的代码中,我使用的是java.sql.PreparedStatement
。
然后我执行setString()
方法来填充预准备语句的通配符。
在调用executeQuery()
方法并执行查询之前,有没有办法检索(并打印出)最终查询?我只想将其用于调试目的。
#1 热门回答(134 赞)
这在JDBC API合同中没有任何定义,但是如果你是幸运,那么有问题的JDBC驱动程序可以通过调用PreparedStatement#toString()
来返回完整的SQL。即
System.out.println(preparedStatement);
根据我的经验,这样做的至少是PostgreSQL 8.x和MySQL 5.x JDBC驱动程序。对于JDBC驱动程序不支持它的情况,最好的办法是使用一个语句包装器,它记录allsetXxx()
方法,最后根据记录的信息在toString()
上填充一个SQL字符串。例如Log4jdbcorP6Spy。
#2 热门回答(25 赞)
在设置绑定值后,可以尝试在预准备语句中调用toString()
。
PreparedStatement query = connection.prepareStatement(aSQLStatement);
System.out.println("Before : " + query.toString());
query.setString(1, "Hello");
query.setString(2, "World");
System.out.println("After : " + query.toString());
这在你使用JDBC MySQL驱动程序时有效,但我不确定它是否会在其他情况下使用。你可能必须跟踪所有绑定,然后打印出来。
上面代码的示例输出。
Before : com.mysql.jdbc.JDBC4PreparedStatement@fa9cf: SELECT * FROM test WHERE blah1=**NOT SPECIFIED**and blah2=**NOT SPECIFIED**
After : com.mysql.jdbc.JDBC4PreparedStatement@fa9cf: SELECT * FROM test WHERE blah1='Hello' and blah2='World'
#3 热门回答(18 赞)
对于那些寻找Oracle解决方案的人,我从Log4Jdbc的代码中创建了一个方法。你需要提供查询和传递给preparedStatement的参数,因为从中检索它们有点痛苦:
private String generateActualSql(String sqlQuery, Object... parameters) {
String[] parts = sqlQuery.split("\\?");
StringBuilder sb = new StringBuilder();
// This might be wrong if some '?' are used as litteral '?'
for (int i = 0; i < parts.length; i++) {
String part = parts[i];
sb.append(part);
if (i < parameters.length) {
sb.append(formatParameter(parameters[i]));
}
}
return sb.toString();
}
private String formatParameter(Object parameter) {
if (parameter == null) {
return "NULL";
} else {
if (parameter instanceof String) {
return "'" + ((String) parameter).replace("'", "''") + "'";
} else if (parameter instanceof Timestamp) {
return "to_timestamp('" + new SimpleDateFormat("MM/dd/yyyy HH:mm:ss.SSS").
format(parameter) + "', 'mm/dd/yyyy hh24:mi:ss.ff3')";
} else if (parameter instanceof Date) {
return "to_date('" + new SimpleDateFormat("MM/dd/yyyy HH:mm:ss").
format(parameter) + "', 'mm/dd/yyyy hh24:mi:ss')";
} else if (parameter instanceof Boolean) {
return ((Boolean) parameter).booleanValue() ? "1" : "0";
} else {
return parameter.toString();
}
}
}