如何在java中获取MySQL异常的catch块中的查询字符串?

如何在java中获取MySQL异常的catch块中的查询字符串?,java,mysql,sqlexception,Java,Mysql,Sqlexception,如何获取MySQL服务器在引发异常时接收到的SQL查询? 我有一个类似于以下的代码: Connection con = null; PreparedStatement ps = null; try { con = DbConnectionManager.getConnection(); ps = con.prepareStatement(query); setStatementParameters(ps, params); ps.executeUpdate();

如何获取MySQL服务器在引发异常时接收到的SQL查询?

我有一个类似于以下的代码:

Connection con = null;
PreparedStatement ps = null;
try {
    con = DbConnectionManager.getConnection();
    ps = con.prepareStatement(query);
    setStatementParameters(ps, params);
    ps.executeUpdate();
} catch (SQLExeption e) {
    // How to get wrong query here?
} finally {
    DbConnectionManager.closeConnection(ps, con);
}
其中查询变量类似于“插入
someTable
qwe
asd
)值(?,)”

问题是如何在catch块中获取查询字符串?

SQLException的异常消息中可能包含查询字符串,也可能不包含查询字符串。你不能依赖它。不过,如果您只是想查看它以进行调试,那么这可能是您最好的选择。但是,在这个特定的示例中,这不是问题,因为您可以直接访问最初用于设置查询的
query
变量。

我遇到了这个问题的另一个解决方案

MySQL JDBC驱动程序重写PreparedStatement的toString,以便在将查询发送到数据库时显示查询。这是依赖于实现的,所以它可能不是最好的依赖,但它非常简单。我现在使用它将查询文本转储到日志文件以进行调试。虽然可能还有其他更具可移植性和经得起未来考验的解决方案,但这样做的好处是可以准确获取MySQL驱动程序所说的发送到数据库的字符串

字符串返回时带有一个对象ID,然后是冒号,然后是SQL字符串。您可以在冒号上拆分它,只得到SQL

类型com.mysql.jdbc.PreparedStatement还公开了一个受保护的方法调用asSql()。您可以使用自己的实现覆盖该类,该实现为该方法提供公共访问权限。从类的toString()方法的反汇编来看,它似乎是在使用asSql()来获取实际的SQL字符串。这种方法增加了如何实例化子类的问题;最简单的方法就是使用您已经有权访问的toString,甚至不必将PreparedStatement向下转换为MySQL特定的子类型

再次,请注意MySQL API的维护者可能不会将公共接口的这部分考虑到他们的软件(JDBC定义了标准接口),因此他们可能会在稍后进行更改,从而破坏该机制。不过,就目前而言,它将完成这项工作


我目前使用的MySQL驱动程序版本是5.1.7。

query变量不包含final query。你的意思是你想用中替换的参数来查看它吗?这是在私有成员变量中,你可以在调试器中看到它,但我不认为有任何方法可以从代码中获得它。(除了修改MySQL JDBC驱动程序源代码之外,您还可以这样做。)