Array de Parametros com PreparedStatement

8 respostas
B

Pessoal,

Tenho uma série de consultas sql que precisam de uma lista de parâmetros do tipo

... WHERE (cod_regiao = 10 OR cod_regiao = 20 OR cod_regiao = 100) AND (data = '12/02/2002/ OR data = '01/01/2000' OR data='01/09/200')
Atualmente eu tenho de passar esses parâmetros data e cod_regiao montando a sql na mão, o que é imcomodo, mas ao mesmo tempo não sei como usar algo há pré-definido no JDBC que atenda minha necessidade, visto que os parâmetros a serem repassados podem ter uma faixa de 2 a 200.

Alguém conhece uma forma de eu não precisar fazer o sql na mão?

Gustavo Guilherme BacK

8 Respostas

brlima

Que eu me lembre, tem naum… :roll:
Monta uma coisinha simples ai pra ler e montar o SQL pra vc, tipo

String sql ( String field_name, String [] values ){
   StringBuffer sqlMontada = new StringBuffer("");
   for( int val=0; val<values.length;val++){
      if( val > 0 ) sqlMontada.append(" AND ");
      sqlMontada.append(field_name + "=" + values[val]);
   }
   return sqlMontada.toString();
}

Acho que isso deve melhorar… :lol:

N

Tem até uma forma de fazer, mas pode dar mais trabalho que a solução que vc está usando.

O PreparedStatement tem comandos setXXX(index, valor), através de um laço for você poderia executar os setXXX com um valor de index variando.

Mas, você precisaria de uma definição do tipo de parâmetro para definir se usar setInt, setDate, setString, etc. Algo como um vetor de tipos, e um vetor de valores.

Se você pode ter uma faixa de 200 parâmetros, talvez possa ajudar.

:oops:

A

Outra coisa que vc pode fazer, que fica muito bonito é pegar carona na idéia do tio Gavin King e montar o PreparedStatement da mesma maneira que o Hibernate faz.
Eu tive de implementar isso, pois os parâmetros de minhas queries não possuiam ordem devido ao uso de condições de inclusão ou não.

Ex.

StringBuffer buffer = new StringBuffer();
buffer.append(“select * from fruta where nome = :none and tipo = :tipo” and data = :data");

if(estacao.equals(primavera)){

buffer.append(" and estacao = :estacao");

}
Map map = new HashMap();

map.put(nome,banana);

map.put(tipo,nanica);

map.put(data,new GregorianCalendar());

map.put(estacao,estacao);

ResultSet rs = SQLWrapper.executeQuery(query,map);

Obs. SQLWrapper é quem fará a mágica, substituindo os parâmetros “:nome, :tipo e :data”, pelos respectivos valores encontrados no Map.

Desta forma, vc não perde a sequência dos parâmetros no PreparedStatement, se vc for adicionar ou não mais conteúdo na query.

Espero ter ajudado.

[]'s

JSnake

Rafael_Steil

Alguem sabe dizer pq o Statement/PreparedStatement nao tem um setXxx literal, como o callableStatement? acho maior furada isso.

Rafael

brlima

Isso significa que o SQLWrapper vai somente substituir os valores? Assim como um “REPLACE” ? Pelos valores que se encontram na map…

No caso de ter mais de um valor para o campo ( ex:" where cd = a or cd = b or cd = c…" ) mesmo assim ele só irá substituir uma vez, não é?
:roll:

Rafael_Steil

eh um replaceAll() que eh chamado, nada alem disso.

Eu fiz uma implementacao parcial ( aka, nao finalizadata/testada ) dessa funcionalidade, que, ao inves de simplemente dar o replace, ele “converte” para o formato de um statement normal ( usando ? ), e entao deixa em cache.

Mas deveria ter na API…

Rafael

A

Bruno,

Isso mesmo. Não importa o que vc faz na query, ele só ira substituir o parâmetro “:sei_la_o_q” pelo respectivo ? na query, e colocar o valor mapeado num List para set do valor no PreparedStatement. Ex.

“…where data between :dataInicio and :dataFim…”

o seu Map deve conter os valores para os parâmetro chave :dataInicio e :dataFim.
Em seguida, vc substitui os parâmetros “:sei_la_o_q” por “?”.
Mas não se esqueça que os parâmetros “:sei_la_o_q”, servem para que vc criar um List (pois tem que obedecer ordem), que fará então os famosos set’s (ordenados) no PreparedStatement.

Qquer coisa, estamos aí…

[]'s

JSnake

Isso significa que o SQLWrapper vai somente substituir os valores? Assim como um “REPLACE” ? Pelos valores que se encontram na map…

No caso de ter mais de um valor para o campo ( ex:" where cd = a or cd = b or cd = c…" ) mesmo assim ele só irá substituir uma vez, não é?
:roll:

brlima

JSnake,

Bem melhor que utilizar os famosos ‘?’ … Será que tambem funciona na chamada de procedure ( CallableStatement ) ?? :stuck_out_tongue:

Depois vou testar…

Value Snake!.. 8)

Criado 8 de dezembro de 2003
Ultima resposta 18 de dez. de 2003
Respostas 8
Participantes 5