Ajuda com Tres Camadas

14/07/2008

1

Senhores, tenho uma dúvida. Estou melhorando um sistema em Tres Camadas na minha empresa.
Essa melhore é retirar todos os CommandText do lado cliente e colocar no lado Servidor de Aplicação.
Só que me deparei om um pequeno probleminha. Nesse select eu tenho um IF. Caso uma situação do IF
for atendida então o Select tem um AND..., caso contrário não. Como esse Selecet é partido em duas partes
antes e depois do IF, tenho um dúvida de como fazer. Lembrando que o IF é somente no lada Cliente. Não
tem como colocá-lo no lado Servidor, por razões óbvias, senão deixaria de ser Tres Camadas. Abaixo o
Select como está hoje.
´SELECT ´ + ´ SEC.CDG_SECAO,PROD.CDG_PRODUTO,PROD.DESC_PRODUTO,PA.CDG_PRODUTO, ´ + ´ PA.MES_ESTOQUE_PA,PA.CDG_COR,CDG_TAM, ´ + ´ (PA.QTDE_ESTOQUE_PA + PA.QTDE_ESTOQUE_PA_OUT) PECAS ´ + ´ FROM ´ + ´ TB_CTRL_PRODUTO PROD, TB_CTRL_ESTOQUE_PA PA, TB_CTRL_SECAO SEC ´ + ´ WHERE ´ + ´ PROD.CDG_PRODUTO = PA.CDG_PRODUTO AND PA.CDG_SECAO = SEC.CDG_SECAO´; if (rbProdEsp.Checked = True) and (LKP_Produto.Text <> ´´) then Sql := Sql + ´ AND PROD.CDG_PRODUTO = ´ + LKP_Produto.Text; Sql := Sql + ´ ORDER BY ´ + ´ PROD.CDG_PRODUTO,PA.CDG_PRODUTO,PA.MES_ESTOQUE_PA, ´ + ´ PA.CDG_COR, PA.CDG_TAM´;



Responder

Posts

14/07/2008

Fabianosales

Uma maneira direta de fazer isso, seria criar dois providers e duas queries no servidor de aplicações, porém, muito embora isso resolva o problema, o desperdício de recursos nessa abordagem é obvio (sempre haverá pelo menos dois componentes não utilizados, um DataSetProvider e um SQLQuery, por exemplo).

Um outro jeito (menos simples e mais correto), seria criar um método publicado no RemoteDataModule que receberia os parâmetros, montatia a query e retornaria o nome do provider ao qual o ClientDataSet local deveria se conectar.


Responder

14/07/2008

Paulo

A primeira hipótese foi a que eu fiz. Isso eu não quero, pois requer duplicação de códigos, praticamente, mas atualmente está assim. A segunda deve ser a mais correta, pois minhas funcções estão assim, ou seja, um método somente para executá-las e receber parâmetros dos Clientes, mas não pensei em fazer com Querys simples.


Responder

14/07/2008

Luiz Henrique

Paulo Bom dia, tudo blz...vamos compartilhar entao...
Tenho uma funcao que uso para isto, ´meio geral´ para SQL com determinada ´magnitude´...retorna sempre a consulta no formato CDS.Data, assim pode ser ainda analisado no cliente, se for o caso:

//Servidor
function RetornaSQL(nID: Double; aParametros: OleVariant): OleVariant;
safecall;

nID: Constantes identificadoras da requisicao SQL, exemplo: ANALISE_VENDAS_VENDEDOR_SINTETICO,
DC_REL_DUPL_MERCANTIL e etc...
aParametros: um array of OleVariant, assim passo qualquer tipo de parametro e sem limite...
Uso sempre uma especie de ´interface´ no cliente, para este caso é essencial, no cliente voce trata a chamada antes de passar para o servidor. Exemplo no teu caso:

formulario/cliente:
CDS.Data:= MeuDMCliente.RetornaSQL(PRODUTOS_ESTOQUE,[rbProdEsp.Checked, LKP_Produto.Text]);

//Converte a array em OleVariant e executa o metodo no Servidor.
Function MeuDMCliente.RetornaSQL(_id_sql: Double;
aParametros: array of OleVariant): OleVariant;
var
i, ii : Integer;
ParArray : OleVariant;

begin
ii := 0;
for i := Low( aParametros ) to High( aParametros ) do begin
inc( ii );
end;

//Cria Array de Parametros
if ii > 0 then begin
ParArray := VarArrayCreate( [ 0, ii -1 ], varVariant );

ii := 0;
for i := Low( aParametros ) to High( aParametros ) do begin
ParArray[ ii ] := aParametros[ i ];
inc( ii );
end;
end
//Funcao sem Parametros, informa...
else begin
ParArray := VarArrayCreate( [ 0, 1 ], varVariant );
ParArray[0]:= Null;
end;

Result:= SConPrincipal.AppServer.ClasseRelatorio.RetornaSQL(_id_sql,
ParArray);
end;

//No servidor...teu metodo publico declarado ....fica assim
...RetornaSQL(nID: Double;
aParametros: OleVariant): OleVariant;
var
//As variaveis a titulo de ilustracao e facilitar o exemplo
//Poderam ser mais ´genericas´ para serem usadas nas outras
// SQL da rotina, e nao ficar declarando um caminhao de variaveis
// para cada SQL implementada na funcao.

bProdEsp: boolean;
sLKP_Produto: string;
begin
if nID = PRODUTOS_ESTOQUE then begin
bProdEsp:= aParametros[0];
sLKP_Produto:= aParametros[1];

....monta/trata/retorna teu SQL

end
else if nID ......Outras requisicoes

....

Funcao bem dinamica pela array de parametros...

Espero que ajude, Abraço T+


Responder

15/07/2008

Paulo

Olá Luiz, vou testar hoje sua função e posto o Result da mesma. Valeu!!!


Responder