Consulta ao Banco Mysql usando LIKE

Colegas,

Vcs sabem informar se há limite de caracteres a serem passados como parâmetro para o comando like?

[code]String sql = “delete from Contas where statusconta = 0 and descricao like ?”;
PreparedStatement stmt = conexao.prepareStatement(sql);
stmt.setString(1, “%”+ trechoUsadoParaDeletar+"%");
stmt.execute();
stmt.close();

[/code]

O que ocorre é o seguinte: se eu tiver no banco uma tabela contas com a coluna descricao:

DESCRICAO
compra de material eletrico
compra de material cirurgico
compra de material de limpeza

quando eu passo como parametro compra de material eletrico ele deleta tudo…

talvez entenda somente compra de mat…(não sei se é bem isso ai…)

então tô achando que há limite de caracteres para o like?

alguém já passou por isso?

Vlw!

SandroSoftwares ,

  O Problema de vc usar um like para excluir não é uma boa pratica, normalmente usamos o like para consultas e so quando realmente não tem geito, poís o like acaba deixando a busca um quanto pesada e dessa forma que está querendo fazer vc vai acabar tendo problemas e vai acabar deletando informações que não seria para deletar. O que eu lhe oriento a fazer colocar ids as essas descriçoes ou fazer alguma outra amarração com outra tabela para ter uma segurança para efetuar essas exclusões.

Jhoni, já tinha notado isso que você falou, por isso me garanti de que o que está sendo passado como parametro existe na tabela.

o problema é que quanto a essa cadeia de caracteres aceita pelo like, parece que há limitações de tamanho… (qual eu não sei…)

vlw…

Sandro

SandroSoftwares,

Pelo tamanho do texto que vc está mostrando de exemplo não é para dar problema, tanto que eu fiz alguns testes por aqui e excluiu o cara certo agora as limitações do like ele suporta o tamanho de uma String.

[quote=SandroSoftwares]Jhoni, já tinha notado isso que você falou, por isso me garanti de que o que está sendo passado como parametro existe na tabela.

o problema é que quanto a essa cadeia de caracteres aceita pelo like, parece que há limitações de tamanho… (qual eu não sei…)

vlw…

Sandro[/quote]

Mesmo que houvesse, esta limitação seria, no mínimo, de 255 caracteres (como o tamanho máximo de campos varchar).
Sugiro que você debugue e veja o que aparece na variável trechoUsadoParaDeletar.

Ou, se quiser testar, rode o SQL na mão mesmo, trocando o ? pelo ‘%trecho_que_quer_deletar%’

String sql = "delete from Contas where statusconta = 0 and descricao  like '%?%' "; // tenta assim
   PreparedStatement stmt = conexao.prepareStatement(sql);
      stmt.setString(1, "trechoUsadoParaDeletar");
        stmt.execute();
        stmt.close();
System.out.println(trechoUsadoParaDeletar); // da uma conferida no valor da variavel, para ter certeza de que está sendo passado a String que você quer

[quote=ganondorfan] String sql = "delete from Contas where statusconta = 0 and descricao like '%?%' "; // tenta assim
[/quote]
Isso não funciona.
O PreparedStatement lançará uma SQL Exception, pois ele não conseguirá compreender essa query

delete from Contas where statusconta = 0 and descricao  like '%'blablabla'%';

[quote=drsmachado][quote=ganondorfan] String sql = "delete from Contas where statusconta = 0 and descricao like '%?%' "; // tenta assim
[/quote]
Isso não funciona.
O PreparedStatement lançará uma SQL Exception, pois ele não conseguirá compreender essa query

delete from Contas where statusconta = 0 and descricao  like '%'blablabla'%';

[/quote]

[i]Só abre uma aspa no like.

Veja:[/i]

delete from Contas where statusconta = 0 and descricao  like '%blablabla%';

[quote=c0nf1ck][quote=drsmachado][quote=ganondorfan] String sql = "delete from Contas where statusconta = 0 and descricao like '%?%' "; // tenta assim
[/quote]
Isso não funciona.
O PreparedStatement lançará uma SQL Exception, pois ele não conseguirá compreender essa query

delete from Contas where statusconta = 0 and descricao  like '%'blablabla'%';

[/quote]

[i]Só abre uma aspa no like.

Veja:[/i]

delete from Contas where statusconta = 0 and descricao like '%blablabla%'; [/quote]
Camarada, você pegou o bonde na metade do caminho…

Eu havia dito que a sugestão do ganodorfan não seria viável, visto que a função do PreparedStatement é justamente evitar coisas daquela natureza.
Quando temos um ? na query e invocamos qualquer PreparedStatement.setAlgumaCoisa, ele mesmo coloca as aspas simples.
Como ele havia sugerido fazer isso

String sql = "delete from Contas where statusconta = 0 and descricao  like '%?%' "; // tenta assim

Disse que, quando o preparedStatement tentar executar a query no MySQL, ela chegará assim

delete from Contas where statusconta = 0 and descricao  like '%'blablabla'%';

E isso lançará erro de sintaxe
Entendeu agora?

drsmachado tem razão, de fato é gerado um erro de compilação.

Acabei de realizar testes aqui, e só consigo um resultado correto com LIKE quando uso ele statico dentro da String, ou seja, quando não utilizo o placeHolder “?” junto com o preparedStatement, logo se eu precico realizar uma operação dinâmica com o comando LIKE, acho que a solução que encontrei a priori é compor a String da Query sem utilizar do PlaceHolder (o que de fato seria uma má pratica, pois tira a segurança de compilação que o PreparedStatement oferece).

Se alguém souber outra maneira de fazer o Like funcionar adequadamente utilizando PlaceHolder, também estou interessado.

[]'s Paulo.

Obrigado a todos!

Realmente o que havia de errado era o que eu estava passando como parâmetro no trechoUsadoParaDeletar

String sql = "delete from Contas where statusconta = 0 and descricao like ?"; PreparedStatement stmt = conexao.prepareStatement(sql); stmt.setString(1, "%"+ trechoUsadoParaDeletar+"%"); stmt.execute(); stmt.close();

a string estava vindo nula por isso ele deletava tudo!

quando a preenchi da forma correta não houve problema algum… ou seja, a questão do limite do parametro pro like foi erro meu…

Sandro

Este like não funciona da maneira como é pra ser, de fato ele não gera erros, mas ele não atinge as linhas corretas.

[quote=ganondorfan]drsmachado tem razão, de fato é gerado um erro de compilação.

Acabei de realizar testes aqui, e só consigo um resultado correto com LIKE quando uso ele statico dentro da String, ou seja, quando não utilizo o placeHolder “?” junto com o preparedStatement, logo se eu precico realizar uma operação dinâmica com o comando LIKE, acho que a solução que encontrei a priori é compor a String da Query sem utilizar do PlaceHolder (o que de fato seria uma má pratica, pois tira a segurança de compilação que o PreparedStatement oferece).

Se alguém souber outra maneira de fazer o Like funcionar adequadamente utilizando PlaceHolder, também estou interessado.
[]'s Paulo.[/quote]
Utilizando apenas JDBC, seria como o sandrosoftwares fez, concatenando os coringas à variável. Não é tão elegante, mas é funcional.

ganondorfan

funcionou agora cara!

eu estava mandando uma string nula por isso dava o problema de deletar tudo…

mas quando preenchi a string com o trecho a deletar correto ele deletou certinho!

Sandro

Eu realizei testes aqui, e o que o sandro fez pode até ter resolvido o problema de deleção dele, entretanto olhe o exemplo abaixo:

public class Ola {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		try{
		Conexao con = new Conexao();
		con.conectarODBCPersonalizado("TC");
		String busca = "LAY";
		PreparedStatement pst = con.getCon().prepareStatement("select * from OPERADORES where nome like ?");
		pst.setString(1, "%"+busca+"%");
		
		ResultSet rs = pst.executeQuery();
		
		while(rs.next()){
			System.out.println(rs.getString("nome"));
		}
		}catch(Exception e){
			e.printStackTrace();
		}

	}

}

Existe um registro de nome CLAYTON no banco, entretanto embora não seja gerado nenhum erro, o registro não é retornado, já desta outra forma sim:

public class Ola {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		try{
		Conexao con = new Conexao();
		con.conectarODBCPersonalizado("TC");
		String busca = "LAY";
		PreparedStatement pst = con.getCon().prepareStatement("select * from OPERADORES where nome like '%"+busca+"%'");
		
		
		ResultSet rs = pst.executeQuery();
		
		while(rs.next()){
			System.out.println(rs.getString("nome"));
		}
		}catch(Exception e){
			e.printStackTrace();
		}

	}

}

Estou utilizando SQL Server como fonte de dados, e misteriosamente o método que o Sandro utilizou não retorna nenhum resultado, enquanto a concatenação da String Query resolve o problema. Mas como eu disse anteriormente o uso de concatenação de Strings faz com que o PreparedStatement deixe de oferecer a segurança que ele normalmente oferece compilando a String, ou seja, é uma maneira inadequada de resolver o problema.

Continuo aguardando uma maneira de efetuar buscas com like utilizando preparedStatement.

[]'s Paulo

Eu estou usando Mysql!

poisé um colega meu me confirmou que funciona com MySql, porem porque não funciona no SQL Server?

Bastante incomum esse problema.
Afinal, o comportamento do setString é, em grosso modo, apenas inserir as aspas simples e completar a query.

Vou instalar o MSSQLServer e ver se consigo simular algo.
Não deveria ocorrer isto (mesmo por que, até em Oracle, que é bemmmmmmmmmm mais chato, funciona)