Trigger Before Delete

Firebird

24/11/2010

Pessoal

Tem como implementar esta trigger no Firebird.
Quando deletar uma nota de compra, decrementar os produtos da mesma no estoque.
Tentei fazer a trigger, mas deu erro. Os comandos While, case etc são aceitos na trigger ???

Grato.


 



procedure TfrmCompras.cds_mestreBeforeDelete(DataSet: TDataSet);
begin
With cds_detalhe do
Begin
  DisableControls;
  First;
  While EOF = False do
  Begin
    If dm.TableProduto.Locate('Controle',cds_detalheProduto.Value,[]) = True Then
    Begin
      dm.TableProduto.Edit;
      dm.TableProdutoQtd.Value:=dm.TableProdutoQtd.Value - cds_detalheQuantidade.Value;
      dm.TableProduto.Post;
      dm.TableProduto.ApplyUpdates(0);
      dm.TableProduto.Refresh;
    End;
    Delete;
  end;
  Next;
  cds_detalhe.EnableControls;
end;

Marcos Roberto

Marcos Roberto

Curtidas 0

Respostas

Emerson Nascimento

Emerson Nascimento

24/11/2010

cadê o código da trigger ?
GOSTEI 0
Emerson Nascimento

Emerson Nascimento

24/11/2010

um exemplo:

CREATE OR ALTER TRIGGER VENDAITEM_AD0 FOR VENDAITEM
ACTIVE AFTER DELETE POSITION 0
AS
declare variable NovoSaldo double precision;
begin
  select coalesce(saldo,0)-old.quantidade from produto
  where controle = old.produto into :NovoSaldo;

  if (:NovoSaldo < 0) then
    exception SaldoNegativo;
  else
    update produto set saldo = coalesce(saldo,0)-old.quantidade
    where controle = old.id_produto;
end


GOSTEI 0
Marcos Roberto

Marcos Roberto

24/11/2010

Emerson

Fiz uma alterão e está com erro, vou explicar melhor ;

Exemplo : Tenho a tabela Vendas, ItemVendas e Produtos.
                Ao excluir uma venda, todos os Itens da ItemVendas deverão voltar ao estoque na tabela de Produtos.

Preciso colocar um trigger na tabela Vendas para o evento Before_Delete.

AS
declare variable NovoSaldo double precision;
begin

with ItemVendas do
begin

    while eof = false do
    begin
           select coalesce(saldo,0)-Produtos.quantidade  from Produtos
                    where Produtos.controle = ItemVendas.codproduto into :NovoSaldo;
           if (:NovoSaldo < 0) then
               exception SaldoNegativo;
           else
               update Produtos set Quantidade = coalesce(saldo,0)-ItemVendas.quantidade
               where controle = ItemVendas.codproduto;
    end


end


end
               
GOSTEI 0
Emerson Nascimento

Emerson Nascimento

24/11/2010

quando você diz "ao excluir uma venda", significa que você exclui os registro de venda e itens de venda? ou você simplesmente "flega" a venda dizendo que foi cancelada?

se for uma exclusão física do registro, o trigger que eu te passei faz exatamente o que você precisa, ao excluir cada item da venda.

CREATE OR ALTER TRIGGER ITEMVENDAS_AD0 FOR ITEMVENDAS
ACTIVE AFTER DELETE POSITION 0
AS
begin
  update produtos set quantidade = coalesce(quantidade,0) + old.quantidade
  where controle = old.codproduto;
end

nesse caso basta você excluir a venda e seus itens que o Firebird se encarregará, através da trigger, de alimentar o estoque. não será necessário qualquer código no programa para essa tarefa.




se você apenas marca o registro de venda como deletado/cancelado, faça diferente:

CREATE OR ALTER TRIGGER VENDA_AU0 FOR VENDAS
ACTIVE AFTER UPDATE POSITION 0
AS
declare variable cdproduto integer;
declare variable qtdvenda double precision;
begin
  if (new.status = 'C') then -- cancelado
    for
      select iv.codproduto, iv.quantidade
      from itemvendas iv
      inner join produtos p on p.controle = iv.codproduto
      where iv.codvenda = old.codvenda
    into :cdproduto, :qtdvenda do
    begin
      update produtos set quantidade = coalesce(quantidade,0) + :qtdvenda
      where controle = :cdproduto;
    end
end

nesse outro caso basta você alterar o status da venda para Cancelada/Excluída e o Firebird se encarregará, através da trigger, de alimentar o estoque. não será necessário qualquer código no programa para essa tarefa.

GOSTEI 0
Marcos Roberto

Marcos Roberto

24/11/2010

Emerson

A exclusão é física.
Agora deu certo. Agradecido mais uma vez.


Agora veja se pode me ajudar mais nesta. rsrsrsrsrsrssrsr.

No IBExpert quando excluo a venda, o itemVenda é excluido tambem por uma trigger, e a trigger que vc me passou quando exclui o item já decrementa do Estoque, tudo certo as mil maravilhas.

Agora, na aplicação, quando clicado no botão de Excluir aparece a seguinte mensagem 'Cannot delete master record with details', se no banco as triggers estão fazendo tudo ok, não entendo porque na aplicação dá isto.
Segue o código da exclusão;

procedure TfrmCompras.Btn_ExcluirClick(Sender: TObject);
begin
if MessageDlg('Confirma a Exclusão da Nota?',mtConfirmation, [mbYes,mbNo],0)= mrYes then
  Begin
   Compra1(EditFornec,tipoCompra,EditDoc,EditNumero,EditData,DbGridCompra);
   cds_mestre.Delete;
   cds_Mestre.ApplyUpdates(0);
   EditFornec.SetFocus;
  End
 Else
  Abort;
end;
GOSTEI 0
Wilson Junior

Wilson Junior

24/11/2010

Ele lhe dá esta mensagem porque deve ter algum "cds_Detalhe" utilizando o seu "cds_Mestre".

Espero ter colaborado.
GOSTEI 0
Marcos Roberto

Marcos Roberto

24/11/2010


Pessoal

No DataSetProvider liguei o poCascadeDelete com true e deu certo.
Eureka.

Abração a todos.

GOSTEI 0
POSTAR