Consulta com mais de um parâmetro [RESOLVIDO]

Pessoal, queria saber como fazer um select que pode receber um ou mais parâmetros…

exemplo a consulta abaixo:

SELECT DISTINCT (Dispositivo.Numero) AS Dispositivo, (Dispositivo.CodigoTecnologia) AS CodTecnologia, (Dispositivo.CodigoAPNConfigurada) AS APNConfigurada, (SIMCard.Numero) AS SIMCard, (Linha.Numero) AS Linha, (SIMCard.CodigoOperadora) AS Operadora, (SIMCard.CodigoAPNProvisionada) AS APNProvisionada, (SIMCard.CodigoStatusSIMCard) AS StatusSIMCard, (Processamento.CodigoFonteDados) AS Fonte, (Dispositivo.IMEI) AS IMEI, (SIMCard.IMSI) AS IMSI, (Linha.CodigoStatusLinha) AS StatusLinha, (SIMCard.ConsumoDados) AS ConsDados, (Processamento.MatriculaCadastro) AS Matricula FROM SIMCard, Dispositivo, Linha, Processamento, SIMCardDispositivo WHERE Dispositivo.CodigoTecnologia IN (22, 23) AND SIMCard.CodigoOperadora IN (10,11, 12) AND Linha.CodigoStatusLinha IN (16,15) AND SIMCard.Numero = SIMCardDispositivo.SIMCard_Numero AND SIMCardDispositivo.Dispositivo_Numero = Dispositivo.Numero AND Linha.Numero = SIMCard.NumeroLinha

No in vai ser recebido valores inseridos na tela… só não sei como fazer o select se adaptar a isso…

os valores podem ser só de um campo, ou dos 3, e podendo ser mais de um valor por campo…

Alguem??

NAda? nenhuma luz?

Opa tudo bem intao tudo depende como vc quer pegar os valores da tela mais uma exemplo seria assim

select nome,cidade from cidades;
dai faz assim com uma string que vc passa a sql

String pes;

pes= “select nome, cidade from cidades where nome=”+jtfield.gettext+";"

é um exemplo mais tem n formas de se fazer

Apesar do exemplo do wilkem funcionar, recomendo que nunca use por um grave motivo: Sql Injection.

A forma padrão de fazer isso seria algo assim:


  StringBuilder sql = new StringBuilder("ParteFixaDaQuery");

  List<Integer> tecnologias = ... // recebe a lista de algum lugar
  List<Integer> operadoras = ... // recebe a lista de algum lugar
  List<Integer> status = ... // recebe a lista de algum lugar

  if ( !tecnologias.isEmpty() ) {
    sql.append(" codigotecnologia IN (");
    for(Integer i : tecnologias) {
      sql.append("?,")
    }
  }

  if ( !operadoras.isEmpty() ) { //mesma coisa }
  if ( !status.isEmpty() ) { //mesma coisa }

  PreparedStatement ps = /// cria ps com sql.toString()

  int indicePs = 1; // ou zero, nunca lembro o primeiro
  if ( !tecnologias.isEmpty() ) {
    for(Integer i : tecnologias) {
      ps.setInteger(indicePs++, i);
    }
  }

  //mesma coisa para os outros

Algumas observações:

  • Use sempre PreparedStatement para executar queries.

  • Tem um erro na hora de montar a query, vai sobrar vírgula…um if resolve (to fazendo de cabeça)

  • Se não me engano, o Spring Data faz esse tipo de coisa para você (mas posso estar enganado).
    Se for fazer na mão, crie umas funções auxiliares para esse tipo de trabalho braçal.

  • Repare que você repete os ifs na lista também, o que também não é bom.
    O ideal seria criar uma classe que intermediária para preencher o PreparedStatement de acordo com a query montada.

Valeu wilken e Abel…

Abel vou usar seu jeito pois eu já pego a lista de um JSP, e está beleza… agora vou montar uma classe onde irei preencher essas listas antes de enviar para a DAO… obrigado pela “luz”, rsrs… vou tentando até conseguir… quando eu conseguir eu coloco RESOLVIDO

To fazendo os testes ainda

Mas não sei ainda como fazer para adicionar o preparedstatement…
pois geralmente faço assim

private static final String SQL_PESQUISA_LINHA_UN = ""
			+ "SELECT DISTINCT (Historico.NumeroDispositivo) AS Dispositivo, "

// e chamo assim:

try {
			conn = ConnectionManager.obterConexao();
			ps = conn.prepareStatement(SQL_PESQUISA_LINHA_UN);
			ps.setString(1, linhaUN);

Faço isso tambem? deixo um script naquele sql que vc passou e crio outro com esse modelo que falei?

Minha classe que converte as palavras em código e monta um List de Inteiros…:

public class VerificarRegistroGeraRelatorio {


	public VerificarRegistroGeraRelatorio(String[] MultiplosDadosAtuais) throws Exception,
			IOException, BiffException, ClassNotFoundException, SQLException {

		Verificador(MultiplosDadosAtuais);
	}


	public void Verificador(String[] MultiplosDadosAtuais) {

		List<Integer> tecnologias = null;
		List<Integer> operadoras = null;
		List<Integer> status = null;
		int cod = 0;
		
		for (String mult : MultiplosDadosAtuais) {
			System.out.println("Valor do Vetor: " + mult);
			
			if(mult.contains("Alarmes") || mult.contains("DAF") || mult.contains("TM PORTO") 
					|| mult.contains("Nanocomm") || mult.contains("DAF VII")){
				
				if (mult.contains("Alarmes")){
					cod = 22; 
				} else if (mult.contains("DAF")) {
					cod = 23; 
				} else if (mult.contains("TM PORTO")){
					cod = 24;
				} else if (mult.contains("Nanocomm")){
					cod = 25;
				} else {
					cod = 26;
				}
				
				
				System.out.println("Tecnologia: "+ mult);								
				//CRIA LISTA DE TECNOLOGIAS
				tecnologias = Arrays.asList(cod);
				
			} else if (mult.contains("CLARO") || mult.contains("TIM") || mult.contains("OI") 
					|| mult.contains("CONECTA")){
				
				
				if (mult.contains("CLARO")){
					cod = 10;
				} else if (mult.contains("TIM")){
					cod = 11;
				} else if (mult.contains("OI")){
					cod = 12;
				} else {
					cod = 13;
				}
				
				System.out.println("Operadora: "+ cod);
				
				//CRIA LISTA DE OPERADORAS
				operadoras = Arrays.asList(cod);
				
			} else if (mult.contains("Ativo") || mult.contains("Bloqueado") || mult.contains("Cancelado")){
				
				
				if (mult.contains("Ativo")){
					cod = 16;
				} else if (mult.contains("Bloqueado")) {
					cod = 15;
				} else {
					cod = 14;
				}
				
				System.out.println("Status: "+ mult);
				//CRIA LISTA DE STATUS
				status = Arrays.asList(cod);
				
			} else {
				System.out.println("Campos vazios: " + mult);
			
			}		
		}

		GeraRelatorioDAO dao = new GeraRelatorioDAO();
		dao.listaTecnologias(tecnologias, operadoras, status);
		
	}
}

Minha DAO está assim:

[code]
public class GeraRelatorioDAO {

private static final String SQL_ = "SELECT DISTINCT (Dispositivo.Numero) AS Dispositivo, "
		+ "(Dispositivo.CodigoTecnologia) AS CodTecnologia, "
		+ "(Dispositivo.CodigoAPNConfigurada) AS APNConfigurada, "
		+ "(SIMCard.Numero) AS SIMCard, "
		+ "(Linha.Numero) AS Linha, "
		+ "(SIMCard.CodigoOperadora) AS Operadora, "
		+ "(SIMCard.CodigoAPNProvisionada) AS APNProvisionada, "
		+ "(SIMCard.CodigoStatusSIMCard) AS StatusSIMCard, "
		+ "(Processamento.CodigoFonteDados) AS Fonte, "
		+ "(SIMCard.DataAlteracao) AS DtAlteracao, "
		+ "(Dispositivo.IMEI) AS IMEI, "
		+ "(SIMCard.IMSI) AS IMSI, "
		+ "(Linha.CodigoStatusLinha) AS StatusLinha, "
		+ "(SIMCard.ConsumoDados) AS ConsDados, "
		+ "(Processamento.MatriculaCadastro) AS Matricula "
		+ "FROM SIMCard, Dispositivo, Linha, Processamento, SIMCardDispositivo, Dominio "
		+ "WHERE SIMCard.Numero = SIMCardDispositivo.SIMCard_Numero "
		+ "AND SIMCardDispositivo.Dispositivo_Numero = Dispositivo.Numero "
		+ "AND Linha.Numero = SIMCard.NumeroLinha ";

StringBuilder sql = new StringBuilder("");
		
public List<ConsultaGerarRelatorio> listaTecnologias(List<Integer> tecnologias, List<Integer> operadoras, List<Integer> status){
	Connection conn = null;
	PreparedStatement ps = null;
	
	if ( !tecnologias.isEmpty() ) {
	    sql.append(" AND Dispositivo.CodigoTecnologia IN (");
	    for(Integer i : tecnologias) {
	    	if (tecnologias.isEmpty()){
	    		sql.append("?) ");
	    	} else {
	    		sql.append("?,");
	    	}
	    }
	  }

	  if ( !operadoras.isEmpty() ) { 
	  sql.append(" AND SIMCard.CodigoOperadora IN (");
	    for(Integer i : operadoras) {
	    	if (operadoras.isEmpty()){
	    		sql.append("?) ");
	    	} else {
	    		sql.append("?,");
	    	}
	    }
	  }
	  
	  if ( !status.isEmpty() ) { 
	  sql.append(" AND Linha.CodigoStatusLinha IN (");
	    for(Integer i : status) {
	    	if (status.isEmpty()){
	    		sql.append("?) ");
	    	} else {
	    		sql.append("?,");
	    	}
	    }
	  }
	
	  try { 
	
		  conn = ConnectionManager.obterConexao();
		  ps = conn.prepareStatement(SQL_+sql.toString());
	
		  int indicePs = 1; // ou zero, nunca lembro o primeiro
		  if ( !tecnologias.isEmpty() ) {
		    for(Integer i : tecnologias) {
		      ps.setInt(indicePs++, i);
		      System.out.println("primeiro i: "+i);
		    }
		  }
		  if ( !operadoras.isEmpty() ) {
		    for(Integer i : operadoras) {
		      ps.setInt(indicePs++, i);
		      System.out.println("segundo i: "+i);
		    }
		  }
		  if ( !status.isEmpty() ) {
		    for(Integer i : status) {
		      ps.setInt(indicePs++, i);
		      System.out.println("terceiro i: "+i);
		    }
		  }
		  System.out.println("Saiu isso "+SQL_+sql.toString());
		  
		  	String dispositivo;
		  	String codTecnologia;
			String apnConfigurada;
			String simCard;
			String linha;
			String operadora;
			String apnProvisionada;
			String statusSIMCard;
			String fonte;
			String imei;
			String imsi;
			String statusLinha;
			String consDados;
			String matricula;
		  
		  
			ResultSet rs = ps.executeQuery();

			while (rs.next()) {

				dispositivo = rs.getString("Dispositivo");
				codTecnologia = rs.getString("CodTecnologia");
				apnConfigurada = rs.getString("APNConfigurada");
				simCard = rs.getString("SIMCard");
				linha = rs.getString("Linha");
				operadora = rs.getString("Operadora");
				apnProvisionada = rs.getString("APNProvisionada");
				statusSIMCard = rs.getString("StatusSIMCard");
				fonte = rs.getString("Fonte");
				imei = rs.getString("IMEI");
				imsi = rs.getString("IMSI");
				statusLinha = rs.getString("StatusLinha");
				consDados = rs.getString("ConsDados");
				matricula = rs.getString("Matricula");

				System.out.println(dispositivo + codTecnologia +
						apnConfigurada + simCard + linha + operadora +
						apnProvisionada + statusSIMCard + fonte + imei + imsi +
						statusLinha + consDados + matricula);		

			}
		  
	  } catch (Exception e) {
			e.printStackTrace();
		} finally {
			ConnectionManager.fecharConexao(conn, null, ps);
		}
	  
	  
	  
	return null;
	
}
[/code]

Dei uma arrumada na DAO, só que não to conseguindo colocar uma condição para terminar e tirar a vírgula…

		  if ( !status.isEmpty() ) { 
		  sql.append(" AND Linha.CodigoStatusLinha IN (");
		    for(Integer i : status) {
		    	if (status.isEmpty()){ //ESSA CONDIÇÃO
		    		sql.append("?) ");
		    	} else {
		    		sql.append("?,");
		    	}
		    }
		  }

Consegui assim… eu trato em uma classe as listas com for para mandar combinações de valores, e envio para a DAO…

public List<ConsultaGerarRelatorio> listaTecnologias(List<Integer> tecnologias, List<Integer> operadoras, List<Integer> status){
		Connection conn = null;
		PreparedStatement ps = null;
		
		  if ( !tecnologias.isEmpty() ) {
		    sql.append(" AND Dispositivo.CodigoTecnologia = ? ");
		  }

		  if ( !operadoras.isEmpty() ) { 
		  sql.append(" AND SIMCard.CodigoOperadora = ? ");
		  }
		  
		  if ( !status.isEmpty() ) { 
		  sql.append(" AND Linha.CodigoStatusLinha = ? ");
		  }
		
		  try { 
		
			  conn = ConnectionManager.obterConexao();
			  ps = conn.prepareStatement(SQL_+sql.toString());
		
			  int indicePs = 1; 
			  if ( !tecnologias.isEmpty() ) {
			    for(Integer i : tecnologias) {
			      ps.setInt(indicePs++, i);
			      System.out.println("primeiro i: "+i);
			    }
			  }
			  if ( !operadoras.isEmpty() ) {
			    for(Integer i : operadoras) {
			      ps.setInt(indicePs++, i);
			      System.out.println("segundo i: "+i);
			    }
			  }
			  if ( !status.isEmpty() ) {
			    for(Integer i : status) {
			      ps.setInt(indicePs++, i);
			      System.out.println("terceiro i: "+i);
			    }
			  }