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.