Ajuda para montar cláusula where dinâmica.

Delphi

30/08/2007

Bom dia pessoal..
Estou passando por um problema aqui que é o seguinte:
Na confecção de relatórios tenho várias opções..
Por exemplo no caso de um relatório de produtos.
Tenho as opções de filtro.. Marca, Fornecedor, Referência, Modelo, Linha,Grupo e por ai vai percebem qtas combinações.
Tenho um sql modelo onde faz o select de todos os campos que preciso
Como no exemplo:
SELECT
  P.PROCOD,P.PRODES,P.PROUNI,P.FORCOD,
  P.MARCOD,P.PROQDE,P.LINCOD,P.GRUCOD,
  P.PROCUS,P.PRODSC,P.PROVEN,F.FORNOM AS FORNECEDOR,
  M.MARDES AS MARCA,G.GRUDES AS GRUPO,
  L.LINDES AS LINHA
FROM
  PRODUTOS P
  INNER JOIN FORNECEDORES F ON (P.FORCOD = F.FORCOD)
  INNER JOIN MARCA  M ON (P.MARCOD = M.MARCOD)
  INNER JOIN GRUPOS G ON (P.GRUCOD = G.GRUCOD)
  INNER JOIN LINHA  L ON (P.LINCOD = L.LINCOD)


O problema esta na montagem da cláusula where, pois nem todos os parâmetros necessitam ser passados.
por exemplo
WHERE (P.FORCOD = :CDFOR)
AND   (P.LINCOD = :CDLIN)
AND   (P.GRUCOD = :CDGRU)
AND   (P.MARCOD = :CDMAR)


Agora neste exemplo ai, o usuário pode não especificar todos os parametros, pois ele pode filtrar apenas
por fornecedor (P.FORCOD = :CDFOR) e por ai vai.
Alguém tem alguma rotina ou idéia para melhorar isso de uma forma genérica?
Enquanto no modelo Client/Server, tranquilo, mas estou mudando para Ntier com o RO e todas as instruções sql ficarão do lado servidor ai o bicho pega.. por isso procuro uma solução.

Thank´s
Fausto


Faustoalves

Faustoalves

Curtidas 0

Respostas

Djjunior

Djjunior

30/08/2007

vc tem 2 opções:

1° sempre passa todos os parametros ai ficaria assim:

WHERE (P.FORCOD = :CDFOR OR :CDFOR = -1)
AND (P.LINCOD = :CDLIN OR :CDLIN = -1)
AND (P.GRUCOD = :CDGRU OR :CDGRU = -1)
AND (P.MARCOD = :CDMAR OR :CDMAR = -1)

O problema aqui é que se a tabela for muito grande este equema não é performático, pois, em alguns bancos Oracle por exemplo com isso ele vai ignorar os indices dando full nas tabelas

outra opção (que eu acho melhor)

function montaWhere(CDMAR , CDGRU : string): string;
var sWhere: string;
begin
sWhere := ´´;
if CDMAR <> ´´ then
sWhere := sWhere + ´ P.MARCOD = ´ + CDMAR + ´ and ´;

if CDGRU <> ´´ then
sWhere := sWhere + ´ P.CDGRU = ´ + CDGRU + ´ and ´;

if sWhere <> ´´ then
sWhere := ´Where ´ + copy(sWhere, 1, Length(sWhere) - 4);
Result := sWhere;
end;

a query do relatório fica pronta menos a parte de where adicionando-a da seguinte forma:
queryRel.sql.Add(montaWhere(suasVariaveis));


GOSTEI 0
Sremulador

Sremulador

30/08/2007

tente usar o or
 (CAMPO =:CAMPO OR CAMPO=CAMPO)



GOSTEI 0
POSTAR