Bom dia pessoal.
Recentemente vi aqui no grupo, algumas pessoas precisando usar LIKE nas consultas SQL com Zend\Db, e gostaria de deixara a minha contribuição pra quem precisar.
Bom, hoje, precisei usar uma consulta com filtro duplo de like.
Pra entenderem, tenho uma tabela de usuarios (que tem a coluna name e a coluna code), e precisava fazer um campo que pesquisa pelos dois campos. Ou seja, se o usuário digitasse "João" a consulta precisaria procurar por "João" na tabela pelo campo name mas se digitasse "1238CSF1" a consulta precisaria procurar por "1238CSF1" na tabela pelo campo code.
Como é uma pesquisa em ajax, o resultado tem que vir em tempo real, então sou obrigado a usar LIKE. MAS no meu caso, utilizo PGSql, e pelo que sei o LIKE é case sensitive, mas PRECISO que a busca não considere maiúsculas e minúsculas, ENTÃO pra isso, preciso usar o ILIKE do pgsql.
Vamos por partes. Primeiro chamamos a classe Predicate do Zend e depois instanciamos o Like que precisamos:
// use Zend\Db\Sql\Predicate;
$name = new Predicate\Like
( 'user.name', "%{$query}%" );
Aqui você já poderia usar diretamente no seu where para filtrar (a var $select representa Zend\Db\Sql\Select):
Mas no meu caso, eu preciso de mais um Like:
// use Zend\Db\Sql\Predicate;
$name = new Predicate\Like
( 'user.name', "%{$query}%" );
$code = new Predicate\Like( 'user.code', "%{$query}%" );
Temos então os dois likes que preciso, e agora vamos adicionar uma PredicateSet pra juntar os dois e usá-los com a cláusula OR do SQL:
$select->where(
new Predicate\PredicateSet(
array(
$name,
$code,
),
Predicate\PredicateSet::COMBINED_BY_OR
)
);
Neste ponto, uma busca já funcionaria no MySQL por exemplo (acho que o LIKe do mysql não considera case sensitive estou certo?). Mas como estou utilizando PostGreSQL e preciso utilizar a cláusula ILIKE, então temos que mudar a especificação do nosso predicate, setando o mesmo antes de adicionar no where:
$name->setSpecification('%1$s ILIKE %2$s');
$code->setSpecification('%1$s ILIKE %2$s');
O código todo ficou assim:
// use Zend\Db\Sql\Predicate;
$name = new Predicate\Like
( 'user.name', "%{$query}%" );
$code = new Predicate\Like( 'user.code', "%{$query}%" );
$name->setSpecification('%1$s ILIKE %2$s');
$code->setSpecification('%1$s ILIKE %2$s');
$select->where(
new Predicate\PredicateSet(
array(
$name,
$code,
),
Predicate\PredicateSet::COMBINED_BY_OR
)
);
Existem outras maneiras de usar LIKE no zend (mas eu acho essa a mais elegante), assim como você também pode usar o PredicateSet com outras cláusulas.
No que diz respeito ao ILIKE essa foi a maneira que encontrei de usar ILIKE sem ter que fazer uma nova classe apenas para mudar a especificação. Se alguém tiver uma maneira melhor ou mais legal pra usar ILIKE, por favor compartilhe conosco.
Abraços!!!!!