Recuperar SQL plano de um PreparedStatement - LOG

Estou me perguntando se é possível recuperar o SQL plano com os valores devidamente definidos conforme o banco de dados a partir de um PreparedStatement.

Seria mais ou menos assim:

String sql = "SELECT * FROM usuario WHERE nome = ?"; PreparedStatement ps = conn.prepareStatement(sql); ps.setDate( 1, "adami" );

Depois deste código, gostaria de retornar o texto:

“SELECT * FROM usuario WHERE nome = ‘adami’”;

Desejo fazer isso para criar um arquivo de LOG recuperável para minha aplicação, que trabalha com diversos bancos de dados (Oracle, PostgreSQL, DB2 e Sybase).

Apenas alguns drivers para alguns bancos suportam você obter o “plain SQL”.
São normalmente aqueles bancos que não suportam nativamente* prepared statements e têm de ficar efetuando o parsing de qualquer consulta SQL.
Por exemplo, no caso do MySQL, parece que o método toString() do PreparedStatement lhe retorna o “plain SQL”.
Entretanto, você pode usar um driver especial (acho que é o p6spy) que é posto “na frente” do seu driver do banco, e transforma um PreparedStatement em um Statement normal e permite que você olhe sempre o “plain sql”.
Esse driver obviamente vai diminuir um pouco o desempenho do seu banco, portanto só deve ser usado se você quiser debugar algum problema de consulta mal-construída ou se suas necessidades de log são mais importantes que suas necessidades de desempenho.

  • Nesses bancos, como o Oracle e o MS SQL Server, os métodos do “PreparedStatement” transformam os dados em forma binária e só mandam os dados, não a string SQL, que só é mandada uma vez (quando da montagem do primeiro PreparedStatement) e pode ficar em um cache especial do banco de dados.