Fórum Mudar uma função para uma Stored Procedure? #376284
25/04/2010
0
Pessoal, estou usando esta função aqui para gerar parcelas
Mais esta muito lento quando preciso gerar umas 20 parcelas por exemplo, e gostaria de saber se tem como eu fazer isso tudo por uma Stored Procedure, e se tiver gostaria de um pequeno exemplo para eu poder começar a desenvolver ...
Muito obrigado...
function _Automaticamente_Receber._GerarRegistros(ANumParcelas, ANumDias: Integer): Boolean;
var
I, Dias, tot_parc, t_parcelas : Integer;
nr_doc, client, cont_contab, nomecontacontab, Histor, str_TipoDevedor, strParcelas : String;
dt_lanc, dt_doc : TDateTime;
vl_total, vl_parcela : Real;
begin
Result := False;
with dm.contasreceber do //Busca o dataset do datamodule
begin
try
Dias := 1;
if trim(lbldtlcto.Caption) = '' then
dt_lanc := now
else
dt_lanc := StrTodate(lbldtlcto.Caption);
nr_doc := lblnrdoc.Caption;
if trim(lbldtdoc.Caption) = '' then
dt_doc := now
else
dt_doc := StrToDate(lbldtdoc.Caption);
client := lblcliente.Caption;
cont_contab := lblcontacontabil.Caption;
nomecontacontab := lblnomecontabil.Caption;
tot_parc := StrToInt(lbltotalparcelas.Caption);
vl_total := StrToCurr(lblvltotal.Caption);
//vl_parcela := StrToCurr(lblvlparcelas.Caption);
Histor := lblhistorico.Text;
{:Faço um laço aqui}
t_parcelas := 0;
{:variavel recebendo o valor do form frmCadContasaPagar}
str_TipoDevedor := dm.contasreceberTIPO_DEVEDOR.AsString;
for I := 1 to ANumParcelas do
begin
Dias := I * ANumDias;
with qryLocal do // aqui estou usando uma query local em cache
begin
{:Gera + 1 a cada vez que passa no laço}
t_parcelas := t_parcelas + 1;
strParcelas := IntToStr(t_parcelas);
if qryLocal.Active = False then
qryLocal.Active := true;
Append;
FieldByName('DTLANCAMENTO').AsDateTime := dt_lanc;
FieldByName('TIPO_DEVEDOR').asString := str_TipoDevedor;
FieldByName('NUMERO_DOCUMENTO').asString := nr_doc+'/'+strParcelas;
FieldByName('NUMERO_PARCELA').asString := strParcelas;
FieldByName('DTEMISSAO').AsDateTime := dt_doc;
FieldByName('IDCLIENTE').AsInteger := DM.contasreceberIDCLIENTE.AsInteger; //TODO: aqui preciso verificar
FieldByName('CLIENTE').AsString := client;
FieldByName('CONTA_CONTABIL').AsString := cont_contab;
FieldByName('NOMECONTACONTABIL').AsString := nomecontacontab;
FieldByName('TOTAL_PARCELAS').AsInteger := tot_parc;
FieldByName('VALOR_TOTAL').AsCurrency := vl_total;
//calculo da parcela
vl_parcela := (vl_total / tot_parc) ; //O calculo é o total da fatura / pela quantidade de parcelas
FieldByName('VALOR_DA_PARCELA').AsCurrency := vl_parcela;
FieldByName('HISTORICO').AsString := histor;
FieldByName('LIQUIDADO').AsString := 'N';
FieldByName('BLOQUEADO').AsString := 'N';
if cb1.Checked = True then
FieldByName('DTVENCIMENTO').AsDateTime := IncMonth(dt_doc, I)
else
FieldByName('DTVENCIMENTO').AsDateTime := dt_doc + Dias;
FieldByName('DATAUSER').AsDateTime := Date;
FieldByName('VALOR_PAGO').AsCurrency := 0.00; //SOMENTE QUANDO PAGAR (BAIXA)
// FieldByName('VALOR_DUPLICATA').asCurrency := StrToCurr(lblvlparcelas.Caption);
{ABAIXO FAÇO OS CALCULOS CFE SOLICITADO}
FieldByName('CALCULA_JUROS').AsCurrency := StrToCurr(JvSpinEdit1.Text);
if trim(JvSpinEdit1.Text) = '' then
FieldByName('VALOR_JUROS').AsCurrency := 0.00
else
if RadioGroup1.ItemIndex = 0 then
FieldByName('VALOR_JUROS').AsCurrency := (FieldByName('VALOR_TOTAL').AsCurrency * FieldByName('CALCULA_JUROS').AsCurrency /100)
else if RadioGroup1.ItemIndex = 1 then
FieldByName('VALOR_JUROS').AsCurrency := (FieldByName('VALOR_DA_PARCELA').AsCurrency * FieldByName('CALCULA_JUROS').AsCurrency /100);
// CALCULO MORA
FieldByName('CALCULA_MORA').AsCurrency := StrToCurr(JvSpinEdit2.Text);
if trim(JvSpinEdit2.Text) = '' then
FieldByName('VALOR_MORA').AsCurrency := 0.00
else
if RadioGroup1.ItemIndex = 0 then
FieldByName('VALOR_MORA').AsCurrency := (FieldByName('VALOR_TOTAL').AsCurrency * FieldByName('CALCULA_MORA').AsCurrency /100)
if RadioGroup1.ItemIndex = 1 then
FieldByName('VALOR_MORA').AsCurrency := (FieldByName('VALOR_DA_PARCELA').AsCurrency * FieldByName('CALCULA_MORA').AsCurrency /100);
// CALCULO DESCONTO
FieldByName('CALCULA_DESCONTO').AsCurrency := StrToCurr(JvSpinEdit3.Text);
if trim(JvSpinEdit3.Text) = '' then
FieldByName('VALOR_DESCONTO').AsCurrency:= 0.00
else
if RadioGroup1.ItemIndex = 0 then
FieldByName('VALOR_DESCONTO').AsCurrency := (FieldByName('VALOR_TOTAL').AsCurrency * FieldByName('CALCULA_DESCONTO').AsCurrency /100)
if RadioGroup1.ItemIndex = 1 then
FieldByName('VALOR_DESCONTO').AsCurrency := (FieldByName('VALOR_DA_PARCELA').AsCurrency * FieldByName('CALCULA_DESCONTO').AsCurrency /100);
if CheckBox1.Checked = true then
FieldByName('CK_calcula_juros').AsString := 'S';
if CheckBox2.Checked = true then
FieldByName('CK_calcula_mora').AsString := 'S';
if CheckBox3.Checked = true then
FieldByName('CK_calcula_desconto').AsString := 'S';
if CheckBox4.Checked = true then
FieldByName('gerar_boleto').AsString := 'S';
if CheckBox5.Checked = true then
FieldByName('gerar_duplicata').AsString := 'S';
FieldByName('idempresas').asinteger := StrToInt( frmprincipal.lblidempr.caption ); //grava a ID da empresa
// GRAVA
Post;
ApplyUpdates(0);
Close;
Open;
end;
end;
dm.connection.Commit;
pt_MessageDlg('Processo efetuado com sucesso.', mtInformation, [mbOK], 0);
Result := True;
except
on E: Exception do
begin
dm.connection.Rollback;
pt_MessageDlg('Ocorreu um erro neste processo. ' +#13#13 +'Erro gerado: '+#13+
E.Message + #13#13 + 'Todo o processo foi abortado!', mtError, [mbOk],0);
Result := False;
end;
end;
end;
end;Muito obrigado...
Adriano Dolce
Curtir tópico
+ 0
Responder
Posts
26/04/2010
Emerson Nascimento
claro que é possível fazer com stored procedure, mas tente modificar sua procedure de modo a ficar assim:
function _Automaticamente_Receber._GerarRegistros(ANumParcelas, ANumDias: Integer): Boolean;
var
I, Dias, tot_parc, t_parcelas : Integer;
nr_doc, client, cont_contab, nomecontacontab, Histor, str_TipoDevedor, strParcelas: String;
dt_lanc, dt_doc : TDateTime;
vl_total, vl_parcela : Real;
begin
Result := False;
with dm.contasreceber do //Busca o dataset do datamodule
begin
try
Dias := 1;
if trim(lbldtlcto.Caption) = '' then
dt_lanc := now
else
dt_lanc := StrTodate(lbldtlcto.Caption);
nr_doc := lblnrdoc.Caption;
if trim(lbldtdoc.Caption) = '' then
dt_doc := now
else
dt_doc := StrToDate(lbldtdoc.Caption);
client := lblcliente.Caption;
cont_contab := lblcontacontabil.Caption;
nomecontacontab := lblnomecontabil.Caption;
tot_parc := StrToInt(lbltotalparcelas.Caption);
vl_total := StrToCurr(lblvltotal.Caption);
//vl_parcela := StrToCurr(lblvlparcelas.Caption);
Histor := lblhistorico.Text;
{:Faço um laço aqui}
t_parcelas := 0;
{:variavel recebendo o valor do form frmCadContasaPagar}
str_TipoDevedor := dm.contasreceberTIPO_DEVEDOR.AsString;
with qryLocal do // aqui estou usando uma query local em cache
begin
close;
// qualquer instrução que não retorne registros
sql := 'select * from tabelaparcelas where idcliente is null and valor_total is null';
open;
end;
for I := 1 to ANumParcelas do
begin
Dias := I * ANumDias;
with qryLocal do // aqui estou usando uma query local em cache
begin
{:Gera + 1 a cada vez que passa no laço}
strParcelas := IntToStr( I );
Append;
FieldByName('DTLANCAMENTO').AsDateTime := dt_lanc;
FieldByName('TIPO_DEVEDOR').asString := str_TipoDevedor;
FieldByName('NUMERO_DOCUMENTO').asString := nr_doc+'/'+strParcelas;
FieldByName('NUMERO_PARCELA').asString := strParcelas;
FieldByName('DTEMISSAO').AsDateTime := dt_doc;
FieldByName('IDCLIENTE').AsInteger := DM.contasreceberIDCLIENTE.AsInteger; //TODO: aqui preciso verificar
FieldByName('CLIENTE').AsString := client;
FieldByName('CONTA_CONTABIL').AsString := cont_contab;
FieldByName('NOMECONTACONTABIL').AsString := nomecontacontab;
FieldByName('TOTAL_PARCELAS').AsInteger := tot_parc;
FieldByName('VALOR_TOTAL').AsCurrency := vl_total;
//calculo da parcela
vl_parcela := (vl_total / tot_parc) ; //O calculo é o total da fatura / pela quantidade de parcelas
FieldByName('VALOR_DA_PARCELA').AsCurrency := vl_parcela;
FieldByName('HISTORICO').AsString := histor;
FieldByName('LIQUIDADO').AsString := 'N';
FieldByName('BLOQUEADO').AsString := 'N';
if cb1.Checked then
FieldByName('DTVENCIMENTO').AsDateTime := IncMonth(dt_doc, I)
else
FieldByName('DTVENCIMENTO').AsDateTime := dt_doc;
FieldByName('DATAUSER').AsDateTime := Date;
FieldByName('VALOR_PAGO').AsCurrency := 0.00; //SOMENTE QUANDO PAGAR (BAIXA)
// FieldByName('VALOR_DUPLICATA').asCurrency := StrToCurr(lblvlparcelas.Caption);
{ABAIXO FAÇO OS CALCULOS CFE SOLICITADO}
FieldByName('CALCULA_JUROS').AsCurrency := StrToCurr(JvSpinEdit1.Text);
if trim(JvSpinEdit1.Text) = '' then
FieldByName('VALOR_JUROS').AsCurrency := 0.00
else
if RadioGroup1.ItemIndex = 0 then
FieldByName('VALOR_JUROS').AsCurrency := (vl_total * FieldByName('CALCULA_JUROS').AsCurrency /100)
else if RadioGroup1.ItemIndex = 1 then
FieldByName('VALOR_JUROS').AsCurrency := (vl_parcela * FieldByName('CALCULA_JUROS').AsCurrency /100);
// CALCULO MORA
FieldByName('CALCULA_MORA').AsCurrency := StrToCurr(JvSpinEdit2.Text);
if trim(JvSpinEdit2.Text) = '' then
FieldByName('VALOR_MORA').AsCurrency := 0.00
else
if RadioGroup1.ItemIndex = 0 then
FieldByName('VALOR_MORA').AsCurrency := (vl_total * FieldByName('CALCULA_MORA').AsCurrency /100)
if RadioGroup1.ItemIndex = 1 then
FieldByName('VALOR_MORA').AsCurrency := (vl_parcela * FieldByName('CALCULA_MORA').AsCurrency /100);
// CALCULO DESCONTO
FieldByName('CALCULA_DESCONTO').AsCurrency := StrToCurr(JvSpinEdit3.Text);
if trim(JvSpinEdit3.Text) = '' then
FieldByName('VALOR_DESCONTO').AsCurrency:= 0.00
else
if RadioGroup1.ItemIndex = 0 then
FieldByName('VALOR_DESCONTO').AsCurrency := (vl_total * FieldByName('CALCULA_DESCONTO').AsCurrency /100)
if RadioGroup1.ItemIndex = 1 then
FieldByName('VALOR_DESCONTO').AsCurrency := (vl_parcela * FieldByName('CALCULA_DESCONTO').AsCurrency /100);
if CheckBox1.Checked = true then
FieldByName('CK_calcula_juros').AsString := 'S';
if CheckBox2.Checked = true then
FieldByName('CK_calcula_mora').AsString := 'S';
if CheckBox3.Checked = true then
FieldByName('CK_calcula_desconto').AsString := 'S';
if CheckBox4.Checked = true then
FieldByName('gerar_boleto').AsString := 'S';
if CheckBox5.Checked = true then
FieldByName('gerar_duplicata').AsString := 'S';
FieldByName('idempresas').asinteger := StrToInt( frmprincipal.lblidempr.caption ); //grava a ID da empresa
Post;
end;
end;
qryLocal.ApplyUpdates(0);
dm.connection.Commit;
pt_MessageDlg('Processo efetuado com sucesso.', mtInformation, [mbOK], 0);
Result := True;
except
on E: Exception do
begin
dm.connection.Rollback;
pt_MessageDlg('Ocorreu um erro neste processo. ' +#13#13 +'Erro gerado: '+#13+
E.Message + #13#13 + 'Todo o processo foi abortado!', mtError, [mbOk],0);
Result := False;
end;
end;
qryLocal.Close;
end;
end;
note que a alteração consiste em abrir a tabela uma única vez e aplicar as alterações somente ao sair do loop, evitando vários fechamentos e aberturas da mesma tabela.
veja que o applyupdates é dado uma única vez e, depois de tudo, a tabela é fechada, evitando assim vários procedimentos desnecessários.
observe também que, onde eu pude, fiz uso das variáveis, pois economiza processamento, visto que o FieldByName() faz uma varredura na lista de campos em busca do campo solicitado para depois retornar o valor do campo. como a variável já está com o valor desejado em memória, a performance é melhor com a variável.
se ainda assim vc achar que ficou lentou ou preferir mesmo que seja com stored procedure, basta solicitar que ajudaremos.
function _Automaticamente_Receber._GerarRegistros(ANumParcelas, ANumDias: Integer): Boolean;
var
I, Dias, tot_parc, t_parcelas : Integer;
nr_doc, client, cont_contab, nomecontacontab, Histor, str_TipoDevedor, strParcelas: String;
dt_lanc, dt_doc : TDateTime;
vl_total, vl_parcela : Real;
begin
Result := False;
with dm.contasreceber do //Busca o dataset do datamodule
begin
try
Dias := 1;
if trim(lbldtlcto.Caption) = '' then
dt_lanc := now
else
dt_lanc := StrTodate(lbldtlcto.Caption);
nr_doc := lblnrdoc.Caption;
if trim(lbldtdoc.Caption) = '' then
dt_doc := now
else
dt_doc := StrToDate(lbldtdoc.Caption);
client := lblcliente.Caption;
cont_contab := lblcontacontabil.Caption;
nomecontacontab := lblnomecontabil.Caption;
tot_parc := StrToInt(lbltotalparcelas.Caption);
vl_total := StrToCurr(lblvltotal.Caption);
//vl_parcela := StrToCurr(lblvlparcelas.Caption);
Histor := lblhistorico.Text;
{:Faço um laço aqui}
t_parcelas := 0;
{:variavel recebendo o valor do form frmCadContasaPagar}
str_TipoDevedor := dm.contasreceberTIPO_DEVEDOR.AsString;
with qryLocal do // aqui estou usando uma query local em cache
begin
close;
// qualquer instrução que não retorne registros
sql := 'select * from tabelaparcelas where idcliente is null and valor_total is null';
open;
end;
for I := 1 to ANumParcelas do
begin
Dias := I * ANumDias;
with qryLocal do // aqui estou usando uma query local em cache
begin
{:Gera + 1 a cada vez que passa no laço}
strParcelas := IntToStr( I );
Append;
FieldByName('DTLANCAMENTO').AsDateTime := dt_lanc;
FieldByName('TIPO_DEVEDOR').asString := str_TipoDevedor;
FieldByName('NUMERO_DOCUMENTO').asString := nr_doc+'/'+strParcelas;
FieldByName('NUMERO_PARCELA').asString := strParcelas;
FieldByName('DTEMISSAO').AsDateTime := dt_doc;
FieldByName('IDCLIENTE').AsInteger := DM.contasreceberIDCLIENTE.AsInteger; //TODO: aqui preciso verificar
FieldByName('CLIENTE').AsString := client;
FieldByName('CONTA_CONTABIL').AsString := cont_contab;
FieldByName('NOMECONTACONTABIL').AsString := nomecontacontab;
FieldByName('TOTAL_PARCELAS').AsInteger := tot_parc;
FieldByName('VALOR_TOTAL').AsCurrency := vl_total;
//calculo da parcela
vl_parcela := (vl_total / tot_parc) ; //O calculo é o total da fatura / pela quantidade de parcelas
FieldByName('VALOR_DA_PARCELA').AsCurrency := vl_parcela;
FieldByName('HISTORICO').AsString := histor;
FieldByName('LIQUIDADO').AsString := 'N';
FieldByName('BLOQUEADO').AsString := 'N';
if cb1.Checked then
FieldByName('DTVENCIMENTO').AsDateTime := IncMonth(dt_doc, I)
else
FieldByName('DTVENCIMENTO').AsDateTime := dt_doc;
FieldByName('DATAUSER').AsDateTime := Date;
FieldByName('VALOR_PAGO').AsCurrency := 0.00; //SOMENTE QUANDO PAGAR (BAIXA)
// FieldByName('VALOR_DUPLICATA').asCurrency := StrToCurr(lblvlparcelas.Caption);
{ABAIXO FAÇO OS CALCULOS CFE SOLICITADO}
FieldByName('CALCULA_JUROS').AsCurrency := StrToCurr(JvSpinEdit1.Text);
if trim(JvSpinEdit1.Text) = '' then
FieldByName('VALOR_JUROS').AsCurrency := 0.00
else
if RadioGroup1.ItemIndex = 0 then
FieldByName('VALOR_JUROS').AsCurrency := (vl_total * FieldByName('CALCULA_JUROS').AsCurrency /100)
else if RadioGroup1.ItemIndex = 1 then
FieldByName('VALOR_JUROS').AsCurrency := (vl_parcela * FieldByName('CALCULA_JUROS').AsCurrency /100);
// CALCULO MORA
FieldByName('CALCULA_MORA').AsCurrency := StrToCurr(JvSpinEdit2.Text);
if trim(JvSpinEdit2.Text) = '' then
FieldByName('VALOR_MORA').AsCurrency := 0.00
else
if RadioGroup1.ItemIndex = 0 then
FieldByName('VALOR_MORA').AsCurrency := (vl_total * FieldByName('CALCULA_MORA').AsCurrency /100)
if RadioGroup1.ItemIndex = 1 then
FieldByName('VALOR_MORA').AsCurrency := (vl_parcela * FieldByName('CALCULA_MORA').AsCurrency /100);
// CALCULO DESCONTO
FieldByName('CALCULA_DESCONTO').AsCurrency := StrToCurr(JvSpinEdit3.Text);
if trim(JvSpinEdit3.Text) = '' then
FieldByName('VALOR_DESCONTO').AsCurrency:= 0.00
else
if RadioGroup1.ItemIndex = 0 then
FieldByName('VALOR_DESCONTO').AsCurrency := (vl_total * FieldByName('CALCULA_DESCONTO').AsCurrency /100)
if RadioGroup1.ItemIndex = 1 then
FieldByName('VALOR_DESCONTO').AsCurrency := (vl_parcela * FieldByName('CALCULA_DESCONTO').AsCurrency /100);
if CheckBox1.Checked = true then
FieldByName('CK_calcula_juros').AsString := 'S';
if CheckBox2.Checked = true then
FieldByName('CK_calcula_mora').AsString := 'S';
if CheckBox3.Checked = true then
FieldByName('CK_calcula_desconto').AsString := 'S';
if CheckBox4.Checked = true then
FieldByName('gerar_boleto').AsString := 'S';
if CheckBox5.Checked = true then
FieldByName('gerar_duplicata').AsString := 'S';
FieldByName('idempresas').asinteger := StrToInt( frmprincipal.lblidempr.caption ); //grava a ID da empresa
Post;
end;
end;
qryLocal.ApplyUpdates(0);
dm.connection.Commit;
pt_MessageDlg('Processo efetuado com sucesso.', mtInformation, [mbOK], 0);
Result := True;
except
on E: Exception do
begin
dm.connection.Rollback;
pt_MessageDlg('Ocorreu um erro neste processo. ' +#13#13 +'Erro gerado: '+#13+
E.Message + #13#13 + 'Todo o processo foi abortado!', mtError, [mbOk],0);
Result := False;
end;
end;
qryLocal.Close;
end;
end;
note que a alteração consiste em abrir a tabela uma única vez e aplicar as alterações somente ao sair do loop, evitando vários fechamentos e aberturas da mesma tabela.
veja que o applyupdates é dado uma única vez e, depois de tudo, a tabela é fechada, evitando assim vários procedimentos desnecessários.
observe também que, onde eu pude, fiz uso das variáveis, pois economiza processamento, visto que o FieldByName() faz uma varredura na lista de campos em busca do campo solicitado para depois retornar o valor do campo. como a variável já está com o valor desejado em memória, a performance é melhor com a variável.
se ainda assim vc achar que ficou lentou ou preferir mesmo que seja com stored procedure, basta solicitar que ajudaremos.
Responder
Gostei + 0
26/04/2010
Adriano Dolce
Bom dia Emerson,
Melhorou bastante a performance, acho que vai ficar assim mesmo....
Mais uma vez muito obrigado....Aprendi mais uma
Melhorou bastante a performance, acho que vai ficar assim mesmo....
Mais uma vez muito obrigado....Aprendi mais uma
Responder
Gostei + 0
Clique aqui para fazer login e interagir na Comunidade :)