Ir para conteúdo

POWERED BY:

Arquivado

Este tópico foi arquivado e está fechado para novas respostas.

sidneypsoares

Problemas com Trigger

Recommended Posts

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?

 

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

  • Conteúdo Similar

    • Por dfoliveira82
      Bom dia senhores,
       
      sou novo no Oracle, antes trabalhava com SQL SERVER, e me deparei com algo que ja estou a horas tentando solucionar mas nao consegui.
      Nessa Trigger que vou postar, quando mando compilar ela, fala que esta faltando uma virgula, apos o values, mas nao precisa dela e nao acho onde pode ser essa virgula faltante.
      CREATE OR REPLACE TRIGGER JOBS_CL_INSERE_USUARIO AFTER INSERT OR UPDATE OF EXPORTADA_AVA ON SITE_USUARIOS REFERENCING NEW AS NEW BEGIN INSERT INTO BLACKBEAN.TBL_USERS VALUES (NULL, 'INSERT', NULL, 'db', '0', '0', '0', TO_CHAR(:NEW.CPF), MD5(:NEW.CPF||'port@l'), TO_CHAR(:NEW.CPF), SUBSTRING(:NEW.NOME, 1, INSTR(:NEW.NOME, ' ')-1), SUBSTRING(:NEW.NOME, INSTR(:NEW.NOME, ' ')+1, LEN(:NEW.NOME)), 'email@email.com', NULL, NULL, DATE_TO_UNIX_TS(SYSDATE), NULL, NULL); END; / Se alguem puder me ajudar agradeceria.
    • Por Carlos Antoliv
      Senhores, bom dia.
       
      tenho um campo status. Então, a ideia é mudar o status. Consigo alterar o status quando necessário. Daí, pensei em todas vez que alterar, salvar o id do usuário, data, hora, o último status alterado...
      consigo fazer isso com INSERT, depois do UPDATE.
       
      Nao uso trigger. Até tentei fazer, mas não saiu como eu queria.
       
      Então, para os maiores entendedores do assunto, a melhor prática seria a TRIGGER ou INSERT ? Melhor prática ou o que mais funciona na prática ?
       
      Alguém poderia dissertar sobre isso ?
      Vlw..abço
    • Por mateus.andriollo
      Gostaria de saber se alguém tem uma trigger para fazer log de qualquer tipo de transação de dados em qualquer tabela do banco. Porém, preciso carregar um campo UserName que será setado a cada conexão via login php
      SET @UserName = 'ZeBala' Achei vários exemplos porém tenho q criar um trigger para cada tabela
       
      CREATE TRIGGER roles_audit_au AFTER UPDATE ON `<nome_tabela>` Existe uma forma de não ser direcionada?
    • Por gcors88
      Prezados, desenvolvi um gatilho onde este tem comunicação com outra tabela, uma é a coleta_sinal_vital, e onde o gatilho foi criado é na table  itcoleta_sinal_vital ( esta possui uma fk da primeira), a questão é que dentro do gatilho realizo um select na primeira tabela para consultar o valor inserido em uma coluna da primeira tabela, faço essa consulta baseada nessa fk que esta sendo inserida ou seja where = :new.cd_coleta_sinal_vital, a questão é que no momento em que esse select é executado ele não retorna dado nenhum, acredito que isto ocorre porque a inserção em ambas as tabelas é feito de forma simultânea, pois se comparado posteriormente o valor da coluna sempre é inserido, gostaria de saber se existe alguma forma de aplicar uma espera ou atraso neste gatilho para que ele possa capturar este valor sem problemas, grato!
    • Por José Peixoto
      Olá,
       
      há alguma forma de fazer uma trigger só ser executada depois que a outra executar? 
       
      Por exemplo: a trigger2 só é disparada quando a trigger1 fizer o commit das informações.
       
      Obrigado desde já :)
×

Informação importante

Ao usar o fórum, você concorda com nossos Termos e condições.