Como Buscar uma String em uma ou Mais Colunas no SQL Server
Imagine que você precisa buscar, em uma tabela de clientes, todos os registros que contenham “Renato” na coluna de razão social (Raz_Social). Ou então buscar clientes cujo bairro ou cidade contenham a palavra “Rio”. Esse tipo de busca por trecho de texto é bem comum no dia a dia e o SQL Server oferece mais de uma forma de resolver.
Buscando com LIKE (a forma mais comum)
Para buscar um trecho de texto dentro de uma coluna, a forma mais direta e legível é usar LIKE com o coringa %:
SELECT * FROM TbClientes
WHERE Raz_Social LIKE '%Renato%';
O % antes e depois do termo indica que pode haver qualquer coisa antes e depois de “Renato” dentro do texto. Essa é a abordagem recomendada para a maioria dos casos, por ser mais legível e mais fácil de manter.
Buscando com CHARINDEX
Outra opção é a função CHARINDEX, que retorna a posição em que um trecho de texto aparece dentro de uma string (ou 0, se não encontrar):
SELECT * FROM TbClientes
WHERE CHARINDEX('Renato', Raz_Social) > 0;
O resultado é equivalente ao exemplo com LIKE acima. A vantagem do CHARINDEX aparece quando você precisa saber onde o texto aparece dentro da string, não só se ele existe, ou quando quer buscar o mesmo termo em várias colunas concatenadas de uma vez.
Buscando em mais de uma coluna ao mesmo tempo
Se você precisa buscar um termo que pode estar tanto no bairro quanto na cidade, é possível concatenar as colunas dentro do CHARINDEX:
SELECT * FROM TbClientes
WHERE CHARINDEX('Rio', BAIRRO + CIDADE) > 0;
Atenção com valores nulos: no SQL Server, concatenar uma string com + quando uma das colunas está NULL faz o resultado inteiro virar NULL, o que faz a linha ser ignorada mesmo que o termo exista na outra coluna. Para evitar esse problema, trate os nulos antes de concatenar, com ISNULL ou COALESCE:
SELECT * FROM TbClientes
WHERE CHARINDEX('Rio', ISNULL(BAIRRO, '') + ISNULL(CIDADE, '')) > 0;
Em versões mais recentes do SQL Server (2012 em diante), você também pode usar a função CONCAT, que já trata valores nulos como string vazia automaticamente, sem precisar de ISNULL:
SELECT * FROM TbClientes
WHERE CHARINDEX('Rio', CONCAT(BAIRRO, CIDADE)) > 0;
Com LIKE, o mesmo resultado pode ser obtido comparando cada coluna separadamente, o que também evita o problema de concatenação com nulos:
SELECT * FROM TbClientes
WHERE BAIRRO LIKE '%Rio%' OR CIDADE LIKE '%Rio%';
Case sensitivity
Tanto LIKE quanto CHARINDEX respeitam a collation configurada no banco ou na coluna. Na grande maioria dos bancos em português (com collation case insensitive, como Latin1_General_CI_AS), a busca por “rio” encontra “Rio”, “RIO” e “rio” sem diferenciar maiúsculas de minúsculas. Se o seu banco usa uma collation case sensitive, pode ser necessário aplicar UPPER() ou LOWER() nos dois lados da comparação para garantir que a busca ignore a caixa das letras.
Um cuidado com performance
Tanto LIKE '%termo%' quanto CHARINDEX com % no início do termo (ou aplicado sobre uma expressão concatenada) impedem o SQL Server de usar um índice na coluna, porque a busca precisa varrer o texto inteiro de cada linha. Em tabelas pequenas ou médias isso não costuma ser um problema, mas em tabelas muito grandes, com buscas de texto frequentes, vale considerar o uso de Full-Text Search, um recurso do próprio SQL Server criado especificamente para busca de texto em grandes volumes de dados, com índices otimizados para esse fim.
Conclusão
Para buscas simples de um trecho de texto, LIKE '%termo%' costuma ser a opção mais legível. Já CHARINDEX é útil quando você precisa da posição exata do texto ou quer buscar o mesmo termo em várias colunas concatenadas de uma vez, desde que você trate corretamente os valores nulos com ISNULL, COALESCE ou CONCAT. Para bancos com grande volume de dados e buscas de texto frequentes, avalie migrar para Full-Text Search.