Dúvida com CallableStatement [RESOLVIDO]

14 respostas
V

Pessoal, quando uso CallableStatement, gostaria de poder logar a chamada da sp com dados que são passados para ela. Exemplo:

String sp = "{ CALL SP_INSERT_NOME_IDADE( ? , ? ) }"; callableStatement = connection.prepareCall(sp); callableStatement.setString(1, "Juliano"); callableStatement.setInt(2, 20); ... String chamada = callableStatement.getChamadaDaSP() // Nessa String teria algo como "CALL SP_INSERT_NOME_IDADE( 'Juliano' , 20 )"

Não encontrei nada assim pronto, alguém já viu? Se não, alguém sabe como posso fazer isso?

Obrigado! :thumbup:

14 Respostas

P

O que exatamente você precisa Juliano não entendi sua dúvida?

F

ele quer uma String que represente o SQL que será executado.

F

http://www.javaworld.com/javaworld/jw-01-2002/jw-0125-overpower.html?page=1

P

Teste a solução acima Juliano, mas parece que é indicado somente em modo debug.

F

Pedrosa:
É Possivel obter sem jogar os ? e setando os valores, que eu saiba daria para fazer assim:

sql = { CALL SP_INSERT_NOME_IDADE( '"+par1+"' , '"+par2+"' ) }

Essa String só deve obter os valores no driver via getAlguma coisa, o que foge do alcance, ou estou falando besteira?

Isso quebraria o principal beneficio de se setar os parametros sem precisar esquentar a cabeça com aspas ou com datas.

V

Eu preciso executar o seguinte procedimento:

  • Obter o CallableStatement à partir da String que contém a chamada da sp:String sp = "{ CALL SP_INSERT_NOME_IDADE( ? , ? ) "; callableStatement = connection.prepareCall(sp); - Setar os respectivos valores: callableStatement.setString(1, "Juliano"); callableStatement.setInt(2, 20); // Até aqui, nada demais - E aqui está o meu problema, de alguma forma eu preciso pegar do CallableStatement a String que é a chamada da sp, já com os valores setados, o que, suponho, seria algo + ou - assim: String soluçãoDosMeusProblemas = callableStatement.getStringMágica();
    O pessoal aqui pediu isso p/ poder logar essa informação.
V

fabiocsi:
Pedrosa:
É Possivel obter sem jogar os ? e setando os valores, que eu saiba daria para fazer assim:

sql = { CALL SP_INSERT_NOME_IDADE( '"+par1+"' , '"+par2+"' ) }

Essa String só deve obter os valores no driver via getAlguma coisa, o que foge do alcance, ou estou falando besteira?

Isso quebraria o principal beneficio de se setar os parametros sem precisar esquentar a cabeça com aspas ou com datas.


Sem dúvidas. Fazer assim está fora de questão.

Tb creio que isso esteja à cargo do driver, a dúvida é, como alcançar essa informação???

V

Obrigado pelo artigo fabiocsi, vou ver se consigo resolver com ele, e se conseguir (tomara! :mrgreen: ) coloco a solução aqui!

O

Como é só para log, acho que voce poderia tentar usar um wrapper para o driver de banco de dados do tipo do p6spy.

T

A razão pela qual o Java não define um método para visualizar a string resultante da substituição dos parâmetros no SQL é que muitas vezes ela não ocorre (pelo menos para os bancos de dados Oracle ou MS SQL Server).
Em vez disso, os parâmetros são mandados em forma binária e o servidor SQL pega esses dados, assim como a string com os “?”, verifica se a string existe em um cache de queries e procedures compiladas, e monta tudo.
Eu sei que isso é bom para depuração, mas se você realmente precisa disso, é necessário usar algo que intercepte esses parâmetros, como o tal do p6spy.

Y

Assim como o thingol falou, a recuperação dessa String não ocorre porque ela é processada totalmente pelo servidor.

Exemplo: MySQL. Claro que o driver executa as operações em modo binário, mas vejam: já usaram PreparedStatement’s reais do MySQL?

São assim:

// as linhas abaixo são instruções executadas
PREPARE stmt FROM 'SELECT * FROM users WHERE ID = ?';
SET @userId = 2;
EXECUTE stmt USING @userId;

// outro exemplo:
PREPARE stmt FROM 'CALL SP_INSERT_NOME_IDADE(?, ?)';
SET @param01 = 'Juliano';
SET @param02 = 20;
EXECUTE stmt USING @param01, @param02;

Notem que em nenhum momento existiu realmente uma instrução pronta com os valores. A instrução executada pelos PreparedStatement’s é resolvida diretamente no servidor. Então, mesmo que o driver para o banco executasse tudo enviando String’s de comandos (ou seja, nada em modo binário), ainda assim a instrução nunca existiria.

V

Obrigado pela sugestão, mas creio que não posso usar o p6spy. Suponho que seja um jar (ou não? Não consegui baixar pq o link do download está fora!), e devido à restrições no cliente não posso adicionar qualquer jar no projeto. Tenho que usar até mesmo versões do Struts e do iText pré-definidas!

Acho que o link que o fabiocsi passou é a melhor solução, assim que terminar de implementar posto aqui! Obrigado à todos! :mrgreen:

V

thingol:
A razão pela qual o Java não define um método para visualizar a string resultante da substituição dos parâmetros no SQL é que muitas vezes ela não ocorre (pelo menos para os bancos de dados Oracle ou MS SQL Server).
Em vez disso, os parâmetros são mandados em forma binária e o servidor SQL pega esses dados, assim como a string com os “?”, verifica se a string existe em um cache de queries e procedures compiladas, e monta tudo.
Eu sei que isso é bom para depuração, mas se você realmente precisa disso, é necessário usar algo que intercepte esses parâmetros, como o tal do p6spy.

Yky Mattshawn:
Assim como o thingol falou, a recuperação dessa String não ocorre porque ela é processada totalmente pelo servidor.

Exemplo: MySQL. Claro que o driver executa as operações em modo binário, mas vejam: já usaram PreparedStatement’s reais do MySQL?

São assim:

// as linhas abaixo são instruções executadas
PREPARE stmt FROM 'SELECT * FROM users WHERE ID = ?';
SET @userId = 2;
EXECUTE stmt USING @userId;

// outro exemplo:
PREPARE stmt FROM 'CALL SP_INSERT_NOME_IDADE(?, ?)';
SET @param01 = 'Juliano';
SET @param02 = 20;
EXECUTE stmt USING @param01, @param02;

Notem que em nenhum momento existiu realmente uma instrução pronta com os valores. A instrução executada pelos PreparedStatement’s é resolvida diretamente no servidor. Então, mesmo que o driver para o banco executasse tudo enviando String’s de comandos (ou seja, nada em modo binário), ainda assim a instrução nunca existiria.


Obrigado pela aula pessoal! :thumbup:

V

Pessoal, consegui resolver com o site http://www.javaworld.com/javaworld/jw-01-2002/jw-0125-overpower.html?page=1 que o fabiocsi passou, não vou colocar como ficou aqui pq tem mais de 800 linhas (a classe tem que implementar a interface CallableStatement, são mais de 150 métodos! :shock: ), mas com uma rápida lida no site ninguém vai ter dificuldades para implementar a solução!

Obrigado à todos! :mrgreen:

Criado 10 de janeiro de 2008
Ultima resposta 14 de jan. de 2008
Respostas 14
Participantes 6