Jump to content
Geraldo Silva

trigger para criar e atualizar saldo em uma tabela

Recommended Posts

olá pessoal.

 

sou novo no forum e também no assunto trigger para o mysql e precisei usar este recurso, mas não estou conseguindo chegar ao resultado que gostaria, por isso venho aqui pedir ajuda de vocês.

 

seguinte:

tenho uma tabela 'lancamentos' com o campos [iD;HISTORICO;TIPO;VALOR;SALDO] [Tipo = Debito (D) ou Credito ©] e tenho criar uma trigger pra ser disparada no BEFORE INSERT para calcular o saldo e inserir no campo SALDO. vejam exemplo abaixo que já encontrei em outro post aqui.

CREATE TRIGGER `SaldoAtual` BEFORE INSERT ON `lancamentos`
 FOR EACH ROW BEGIN
  DECLARE saldoAnterior DECIMAL(10,2);

  SET saldoAnterior = (SELECT L.SALDO FROM lancamentos L ORDER BY L.ID DESC LIMIT 1);
  
  IF saldoAnterior <> '' THEN

      IF (NEW.TIPO = 'C') THEN
        SET NEW.SALDO = saldoAnterior + NEW.VALOR;
      ELSE
        SET NEW.SALDO = saldoAnterior - NEW.VALOR;
      END IF;
      
      ELSE
      
      SET NEW.SALDO = NEW.VALOR;
      
  END IF;

END

esse exemplo funciona bem para o insert, mas existe outra dificuldade e não tenho conseguido resolver.

 

Preciso ter outra trigger no BEFORE UPDATE da mesma tabela que se eu alterar um valor anterior por exemplo esta trigger atualize o saldo da linha alterada e de todas as outras linhas que existirem depois dela para que o saldo fique correto.

 

espero ter me feito compreender e se alguém puder me ajudar com algum exemplo eu ficarei muito grato.

Share this post


Link to post
Share on other sites

Bom, ninguém ajudou aqui, mas encontrei uma solução diferente em outro fórum e acho que conhecimento é pra ser compartilhado, então vou postar pra ajudar alguém no futuro a solução simples e que resolveu perfeitamente.Eu coloquei a query abaixo em uma view e o resultado ficou exatamente como eu queria.

SELECT DATE_FORMAT(data,'%d/%m/%Y') AS data,
    SUM(IF(tipo = 'C', valor, 0)) AS credito,
    SUM(IF(tipo = 'D', valor, 0)) AS debito,
    (SELECT SUM(IF(tipo = 'C', valor, -valor)) FROM lancamentos AS L2
         WHERE DATE_FORMAT(lancamentos.data,'%Y%m%d') >= DATE_FORMAT(L2.data,'%Y%m%d')
    ) AS saldo
FROM lancamentos
GROUP BY DAY(data), MONTH(data), YEAR(data) 

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Similar Content

    • By Felipe_N22
      Pessoal, como que eu crio uma rotina no MySQL para efetuar delete de registros inseridos nos últimos 30 dias, e fazer com que esse procedimento rode todos os dias automaticamente em determinado horário?
    • By Angelo_Pacheco
      Olá Pessoal!
      Faz tempo que não trabalho com BD e trigger e estou retornando.
      Estou com a seguinte situação
       
      Tenho 2 tabelas:
      glpi_tickets e glpi_plugin_fields_ticketoramentos
       
      Dentro do formulario ticket (tabela glpi_tickets) criei um campo otimizado chamado reprovado (tabela 
      glpi_plugin_fields_ticketoramentos) A tabela  glpi_plugin_fields_ticketoramentos se relaciona com glpi_tickets
       
      A situação é que se o usuario reprova o ticket, o mesmo terá de ser fechado.
       
      Estou montando a trigger
      CREATE TRIGGER TRG_fechaChamado
      AFTER  UPDATE
      ON glpi_tickets 
      FOR each row
      BEGIN
        
        SELECT g.reprovadofield 
               into @repro  
                    FROM  glpi_tickets t,
                         glpi_plugin_fields_ticketoramentos g
                    WHERE t.id = g.items_id
                    AND   g.reprovadofield = 0
                    AND   t.id = ????
                    
                           
          if @repro = 0 THEN
          
            UPDATE glpi_tickets SET status = 6 WHERE id ????
          
          END IF;
          
      END;
       
      Não estou conseguindo pegar o id do ticket a ser analisado para fechamento.
       
      Podem me ajudar??
       
       
       
       
       
    • By TFernandes89
      Bom dia, preciso atualizar uma linha do meu banco de dados validando duas colunas diferentes... estou tentando da seguinte forma:
       
      update produn set prun_margem=prun_margem + 1 from produtos where prod_codigo=prun_prod_codigo and prun_unid_codigo='003' and prun_unid_codigo='050' and prod_grup_codigo='10003'  
      Tenho que atualizar a margem em +1 somente quando se tratar do grupo (prod_grup_codigo) 10003 e nas unidades (prun_unid_codigo) 003 e 050, dessa forma que estou tentando não me da erro, porem não atualiza nada, e se eu tiro a unidade 050 ele atualiza na unidade 003 normalmente.
    • By sidneypsoares
      Pessoal,
      Sou novo em trigger, agradeceria sua ajuda.
      Tenho um banco de dados de consumo de cliente. Acontece que quando vou inserir nova leitura para o cliente ele deve calcular o consumo atual.
      Mas acontece que pode haver uma virada na medição, ou seja, a leitura anterior está em 9999 e agora está 1, ele deve prever isso.
      Assim criei essa trigger:Gatilhos `historico`
      --
       
      DELIMITER $$ CREATE TRIGGER `consumo_atual` BEFORE INSERT ON `historico` FOR EACH ROW BEGIN DECLARE leitura_anterior int(5); DECLARE tempo int(5); SET leitura_anterior = (SELECT L.tb_leitura FROM historico L WHERE L.tb_instalacao=NEW.tb_instalacao ORDER BY L.tb_data DESC LIMIT 1); SET tempo = (SELECT DATEDIFF( CURRENT_DATE(),L.tb_data) AS valor FROM historico L WHERE L.tb_instalacao=NEW.tb_instalacao ORDER BY L.tb_data DESC LIMIT 1); IF (leitura_anterior <> '' ) THEN IF (NEW.tb_leitura > 0 and tempo >=1 and tempo <=30) THEN IF (NEW.tb_op = 1) THEN CASE WHEN (NEW.tb_diais= '4' AND leitura_anterior > NEW.tb_leitura AND leitura_anterior >= 9000) THEN SET NEW.tb_consumo = ((NEW.tb_leitura - leitura_anterior) + 10000) * NEW.tb_const, NEW.tb_cod = '137'; WHEN (NEW.tb_diais= '5' AND leitura_anterior > NEW.tb_leitura AND leitura_anterior >= 90000) THEN SET NEW.tb_consumo = ((NEW.tb_leitura - leitura_anterior) + 100000) * NEW.tb_const, NEW.tb_cod ='137'; WHEN (NEW.tb_diais= '6' AND leitura_anterior > NEW.tb_leitura AND leitura_anterior >=900000) THEN SET NEW.tb_consumo = ((NEW.tb_leitura - leitura_anterior) + 1000000) * NEW.tb_const, NEW.tb_cod ='137'; ELSE BEGIN SET NEW.tb_consumo = (NEW.tb_leitura - leitura_anterior) * NEW.tb_const; END; END CASE; ELSE SET NEW.tb_consumo = 0; END IF; ELSE SET NEW.tb_consumo = 0; END IF; ELSE SET NEW.tb_consumo =NEW.tb_leitura * NEW.tb_const; END IF; END $$ DELIMITER ;  
      Essa é a estrutura do  banco:
      Estrutura para tabela `historico`
      --
      CREATE TABLE `historico` ( `tb_id` int(11) NOT NULL, `tb_instalacao` varchar(10) NOT NULL, `tb_reg` char(3) NOT NULL, `tb_unidade` varchar(8) NOT NULL, `tb_local` varchar(4) NOT NULL, `tb_razao` varchar(2) NOT NULL, `tb_data` date NOT NULL, `tb_adm` int(11) NOT NULL, `tb_contrato` varchar(10) NOT NULL, `tb_leitura` int(5) NOT NULL, `tb_cod` varchar(4) DEFAULT NULL, `tb_mat` int(11) DEFAULT NULL, `tb_sgl` int(5) DEFAULT NULL, `tb_subsigla` int(5) DEFAULT NULL, `tb_op` int(11) NOT NULL DEFAULT '0', `tb_consumo` float DEFAULT NULL, `tb_provavel` int(6) DEFAULT NULL, `tb_minima` int(6) DEFAULT NULL, `tb_faturada` int(6) DEFAULT NULL, `tb_acerto` int(6) DEFAULT NULL, `tb_obs` varchar(150) DEFAULT NULL, `tb_f1` char(1) DEFAULT NULL, `tb_f2` char(1) DEFAULT NULL, `tb_f3` char(1) DEFAULT NULL, `tb_ver` char(1) NOT NULL DEFAULT 'N', `tb_seq` int(5) DEFAULT NULL, `tb_seqdig` int(11) DEFAULT NULL, `tb_A02` varchar(3) DEFAULT NULL, `tb_nome` varchar(50) DEFAULT NULL, `tb_medidor` varchar(12) NOT NULL, `tb_diais` varchar(3) NOT NULL, `tb_const` int(5) NOT NULL ) ENGINE=InnoDB DEFAULT CHARSET=latin1;
       
      E esse é o registro:
       
      INSERT INTO `historico` ( `tb_instalacao`, `tb_reg`, `tb_unidade`, `tb_local`, `tb_razao`, `tb_data`, `tb_adm`, `tb_contrato`, `tb_leitura`, `tb_cod`, `tb_mat`, `tb_sgl`, `tb_subsigla`, `tb_op`, `tb_consumo`, `tb_provavel`, `tb_minima`, `tb_faturada`, `tb_acerto`, `tb_obs`, `tb_f1`, `tb_f2`, `tb_f3`, `tb_ver`, `tb_seq`, `tb_seqdig`, `tb_A02`, `tb_nome`, `tb_medidor`, `tb_diais`, `tb_const`) VALUES ('3013639052', '03', '01330101', '3301', '01', '2019-05-01', 1, '4680005077', 90001, '1801', 0, 0, NULL, 1, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'N', 1, 1, NULL, 'SIDNEY PORTELA SOARES', 'APC099037055', '5', 1); COMMIT; INSERT INTO `historico` ( `tb_instalacao`, `tb_reg`, `tb_unidade`, `tb_local`, `tb_razao`, `tb_data`, `tb_adm`, `tb_contrato`, `tb_leitura`, `tb_cod`, `tb_mat`, `tb_sgl`, `tb_subsigla`, `tb_op`, `tb_provavel`, `tb_minima`, `tb_faturada`, `tb_acerto`, `tb_obs`, `tb_f1`, `tb_f2`, `tb_f3`, `tb_ver`, `tb_seq`, `tb_seqdig`, `tb_A02`, `tb_nome`, `tb_medidor`, `tb_diais`, `tb_const`) VALUES ('3013639052', '03', '01330101', '3301', '01', '2019-06-01', 1, '4680005077', 7, '1801', 0, 0, NULL, 1, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 'N', 1, 1, NULL, 'SIDNEY PORTELA SOARES', 'APC099037055', '5', 1); COMMIT;
       
       
      Observe que a leitura do cliente em 2019-05-01 foi 90001 e em 2019-05-01 foi 7 e como o campo tb_diais é 5  houve uma virada na medição então o CASE deveria aceitar o calculo :
       
      WHEN (NEW.tb_diais= '5' AND leitura_anterior > NEW.tb_leitura AND leitura_anterior >= 90000) THEN SET NEW.tb_consumo = ((NEW.tb_leitura - leitura_anterior) + 100000) * NEW.tb_const, NEW.tb_cod ='137';  
       
      Mas justamente não está fazendo, ele apenas coloca no consumo o valor 0.
       
      Alguém poderia me ajudar?
       
       
    • By mayconyury
      Galera, boa noite.
       
      Estou com dificuldades para realizar um insert em uma tabela no oracle. 
       
      Criei duas lists, uma buscando o código das filiais existentes em uma tabela e outro para receber as filiais de acordo com a escolha do usuário. Estou realizando um cadastro de produtos por filial, então ao terminar o cadastro o dialog pergunta se quer atualizar os dados em outra filial. Se marcada a opção SIM, abre a tela para escolher para qual filial o usuário quer copiar ( update ). Mas pode existir situações onde o produto não existe, então queria que realiza-se um insert para essas filiais ao invés do update.
       
      Alguém pode ajudar?
       
×

Important Information

Ao usar o fórum, você concorda com nossos Terms of Use.