Momento POG: Facilitando a construção de Filtros SQL (C# e Stored Procedures)
Leonel Fraga de Oliveira 01/08/2008 12:00

E aí, galera, tudo bem?
Hoje vou dar uma dica rapidinha, sobre como montar de forma simplificada filtros dinâmicos para consultas SQL em C# com o mesmo conceito aplicável em Stored Procedures.

Construir um filtro dinâmico para uma consulta SQL é basicamente concatenar strings montando-se a cláusula Where desejada. Por exemplo, em uma tabela com a seguinte estrutura:

	CREATE TABLE EXEMPLO (
		ID integer not null primary key,
		NOME varchar(200),
		RG varchar(9),
		CPF varchar(11),
		SEXO char(1)
	);
	

Suponhamos que será feita uma pesquisa em que a nossa tabela EXEMPLO será filtrada pelos campos NOME, CPF e SEXO com as seguintes condições: O campo somente será incluído na filtragem se o usuário digitar algum valor (ou selecionar, caso ele não seja um campo livre, como em combo-boxes e afins), caso contrário, ele não será incluído na query.
A princípio, montaríamos a nossa instrução de pesquisa em C# assim:

	public DataView MinhaPesquisa(string Nome, string CPF, string Sexo)
	{
		string isql = "select * from EXEMPLO ";
		string strWhere = "";
		ArrayList filtros = new ArrayList();
		
		//Aqui verificamos se o usuáro digitou algo nos campos de pesquisa para montarmos o Where
		if(!Nome.Trim().Equals(""))
			filtros.Add(String.Format("(NOME like '{0}%') ",Nome.ToUpper().Trim()));
		
		if(!Sexo.Trim().Equals(""))
			filtros.Add(String.Format("(SEXO = '{0}') ",Sexo.ToUpper().Trim()));
		
		if(!CPF.Trim().Equals(""))
			filtros.Add(String.Format("(CPF like '{0}') ",CPF.ToUpper().Trim()));
		
		foreach(string s in filtros)
			where += s + " and ";
		
		where = where.Equals("")?"":(" where " + where.Substring(0,where.Length - 4));
		isql = isql + where;
	  
		 ... //Aqui você executa a instrução SQL...
	}
	

Não é muito complicado depois que pega o jeito, o modelo de montagem para qualquer filtro é o mesmo. Declaramos a string que será a nossa instrução SQL (variável isql), nossa cláusula where montada (variável where) e um ArrayList que irá receber os nossos filtros parciais: se o usuário digitar o valor correspondente ao filtro, ele é incluído no ArrayList. Em seguida, essa matriz é varrida e os valores parciais são concatenados em where seguido de um operador SQL and.
Quando terminar o foreach, note que ficará sobrando um "and" no final da string. Então, com o código abaixo do foreach, removemos esse and que ficou sobrando, caso tenha alguma coisa em where (se for vazio, e não fizermos a checagem de string vazia, a instrução Substring irá dar pau).

Mas, para evitar tudo isso, tem uma aplicação prática da POG. Isso mesmo, a famosa Programação Orientada a Gambiarras! Veja como vai ficar a nossa instrução de pesquisa:

	public DataView MinhaPesquisa(string Nome, string CPF, string Sexo)
	{
		string isql = "select * from EXEMPLO where (1 = 1) ";
		isql += Nome.Trim().Equals("")?"":(String.Format(" and NOME like '{0}%' ",Nome.Trim().ToUpper()));
		isql += CPF.Trim().Equals("")?"":(String.Format(" and CPF = '{0}' ",CPF.Trim().ToUpper()));
		isql += Sexo.Trim().Equals("")?"":(String.Format(" and SEXO = '{0}' ",Sexo.Trim().ToUpper()));
		
		...//Execução do SQL
	}
	

O que fizemos: Acrescentamos diretamente em isql uma cláuslua Where que retornará todas as tuplas da tabela se não for especificado nenhum filtro. Caso o usuário digite algo nos campos de pesquisa, a concatenação das cláusulas where serão feitas diretamente em isql e note também que o operador AND foi movido para o início de cada filtro.
Com isso, eliminamos os "if", ArrayList, foreach...
Só não escapamos dos "if" se a nossa query for parametrizada.

Ah, também podemos montar nesse mesmo esquema uma Stored Procedure que retornará um resultset, montando a instrução SQL e os filtros dentro da SP. Vou mostrar o exemplo de uma em FireBird:

	CREATE PROCEDURE SP_MINHA_PESQUISA (
		nome varchar(200),
		cpf varchar(11),
		sexo char(1))
	as
	declare variable "ISQL" varchar(1000);
	begin
		ISQL = 'select * from EXEMPLO where (1=1) ';
		if(not (NOME is null) ) then
			ISQL = ISQL || ' and NOME like ''' || nome || '''%)';
		if(not (CPF is null) ) then
			ISQL = ISQL || ' and CPF = ''' || CPF || ''')';
		if(not (SEXO is null) ) then
			ISQL = ISQL || ' and SEXO = ''' || SEXO || ''')';
		for execute statement ISQL into ... do
		begin
			--faça o que tiver que fazer :-)
		end
	end
	

Viu como o processo é simples? A mesma "técnica" que usamos no C# fizemos em PSQL também :-)

Espero que eu tenha ajudado!

Leonel Fraga de Oliveira Leonel Fraga de Oliveira é formado em Processamento de Dados na Faculdade de Tecnologia de São Paulo (FATEC-SP - 2002) e anteriormente em Técnico em Eletrônica, pela ETE Professor Aprígio Gonzaga (lá em 1999).
Atualmente trabalha como Analista de Sistemas na Prefeitura Municipal de São Caetano do Sul - SP
Tem como hobbies DJing (também trabalha como DJ freelancer) e ciclismo, além da manutenção dos sites NeoMatrix Light e NeoMatrix Tech.
Gosta de música eletrônica, tecnologia, cinema (super fã de Jornada nas Estrelas), gastronomia e outras coisas mais.


Compartilhe nas redes sociais

   

Deixe seu comentário

comments powered by Disqus