How can I get SQL query that was received
by MySQL server when it raises exception?
I have a code similar to the following:
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);
}
Where query variable is like "INSERT into someTable
(qwe
, asd
) VALUES (?, ?)"
The question is how can I get query string in the catch block?
I've run across another solution to this problem.
The MySQL JDBC driver overrides the toString of PreparedStatement to display the query as it is sent to the database. This is implementation dependent so it may not the best thing to rely on, but it's very simple to get at. I'm now using this to dump query text to a log file for debugging purposes. While there are probably other solutions that are more portable and future-proof, this has the advantage of getting exactly the string that the MySQL driver says it's sending to the database.
The string comes back with an object ID, then a colon, then the SQL string. You can split it on the colon to get just the SQL.
The type com.mysql.jdbc.PreparedStatement also exposes a protected method call asSql(). You could override the class with your own implementation that gives public access to this method. From looking at the disassembly of the class's toString() method, it seems to be using asSql() to get the actual SQL string. This approach adds the problem of how to instantiate your subclass, though; the simplest approach is just to use the toString that you already have access to, without even having to downcast your PreparedStatement to a MySQL-specific subtype.
Again, just be aware that the maintainers of the MySQL API probably don't consider this part of the public interface to their software (JDBC defines the standard interface), so they may make changes later that would break this mechanism. For the time being, though, it will get the job done.
This is true for the version of the MySQL driver I'm currently using, which is 5.1.7.