Ajuda para montar cláusula where dinâmica.
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:
O problema esta na montagem da cláusula where, pois nem todos os parâmetros necessitam ser passados.
por exemplo
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
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
Curtidas 0
Respostas
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));
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
30/08/2007
tente usar o or
(CAMPO =:CAMPO OR CAMPO=CAMPO)
GOSTEI 0