Ir para conteúdo

Arquivado

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

cfreis01

[Resolvido] Duvida sobre trigger com update

Recommended Posts

eu tenho uma tabela  funcionário com uma coluna salário e criei uma nova coluna do tipo salário eu pensei em uma trigger

para que todas as vezes que um funcionário receba um aumento, nessa nova coluna seja registrada a quantia do último aumento recebido

mas quando executo o update da erro;

outra duvida dentro do update como o update sabe que é só deste  funcionario? o que colocar na clausula where dentro da trigger?

CREATE OR REPLACE TRIGGER new_salario_emp
BEFORE UPDATE
   ON emp
   FOR EACH ROW
   --
DECLARE
   salario number;
BEGIN
   salario  :=   :new.sal - :OLD.sal;
   --
   update emp set old_salario = salario;
   commit;
 --
END;

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

O mais correto seria gravar uma outra tabela de log , tente ler sobre isto.

 

Todavia no seu exemplo bastaria atribuir o valor a coluna , mas repare que perderá a informação em uma segunda alteração.

 

BEGIN

  :new.old_salario := :OLD.sal;

 

End;

Compartilhar este post


Link para o post
Compartilhar em outros sites

Infelizmente eu não posso criar uma nova tabela,  a ideia foi justamente criar esta nova coluna para guardar o valor que foi dado como aumento.

Sim pode perder..pois a cada updade neste funcionario eu só vou guardar o ultimo valor.

Mas esta correto desta forma que eu fiz?

Pois não esta funcionando esta dando um erro de trigger mutante quando tento fazer um update.

 

Compartilhar este post


Link para o post
Compartilhar em outros sites
13 minutos atrás, Motta disse:

 

Outra dúvida como o update pega apenas o funcionario que esta sendo feito o update como colocar uma clausula where dentro da trigger sabendo o funcionario que esta atualizando o salario?

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

OR EACH ROW a trigger será acionada para csda LINHA da tabela , no caso teu funcionário.

STATEMENT a trigger será acionada pelo declaração toda quantas linhas atinja.

 

Doc

 

https://www.devmedia.com.br/triggers-pl-sql-saiba-quando-e-por-que-usar/30011

 

https://www.devmedia.com.br/criacao-de-triggers-no-oracle/13039

Compartilhar este post


Link para o post
Compartilhar em outros sites

Eu vi que não se pode fazer um update na mesma tabela que esta sendo feito um update

pois gera este erro:

ora - 00060: conflito detectado ao aguardar recurso

Não tem nenhuma forma da trigger atualizar a coluna da minha tabela em que estou fazendo um update pois não é a mesma coluna

estou fazendo este update: update EMP set sal = 1000 where empno = 6799

e quando faço este update na coluna sal_novo a trigger tinha q atualizar pegando o valor novo - valor antigo e guardar e toda vez que eu fizer um update neste cara guardar o ultimo valor

Compartilhar este post


Link para o post
Compartilhar em outros sites
CREATE OR REPLACE TRIGGER new_salario_emp
BEFORE UPDATE--BEFORE POIS SERÁ ALTERADA UMA COLUNA
   ON emp
   FOR EACH ROW--PARA CADA LINHA
   --
DECLARE

BEGIN
   :NEW.old_salario := :OLD.sal;--ATRIBUI O VALOR ANTERIOR DE SAL A old_salario NAO PODE COMMITAR AQUI
 --
END;

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Motta se eu criar uma tabela_log como intermediaria ai inserir após o update e depois que inserir disparar uma outra trigger para atualizar a coluna com o valor do aumento ele da erro: ora-00060: conflito detectado ao aguardar recurso

E se eu coloco ao invés de :new :old_salario ele nao atualiza mas também nao da erro você sabe me dizer por que?

 

CREATE OR REPLACE TRIGGER new_salario_emp
AFTER INSERT
   ON emp_log
   FOR EACH ROW
   --
DECLARE
Pragma Autonomous_Transaction;
--
BEGIN
--
 update emp set old_salario = :new.sal - :new.old_salario where empno = :new.empno;
 commit;
--
END;

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

não , seria algo como

 

CREATE OR REPLACE TRIGGER new_salario_emp
AFTER INSERT
   ON emp --a que dispara o log
   FOR EACH ROW
   --
DECLARE
Pragma Autonomous_Transaction;
--
BEGIN
--
 insert into emp__log (colunas) values);--edite este comando
 --commit; nunca commit em trigger !!!!!!!!!!!!!!!!!!!
--
END;

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

A trigger para inserir na tabela log esta certo funcionando o problema é que preciso atualizar a coluna da tabela emp a minha ideia foi depois que inserir na tabela de log (codigo,salario,data,salario novo) eu ia disparar uma nova trigger before insert emp_log fazer o update na coluna da emp mas da erro

CREATE OR REPLACE TRIGGER new_salario_emp
AFTER INSERT
   ON emp_log
   FOR EACH ROW
     
DECLARE
Pragma Autonomous_Transaction;
BEGIN
update emp
set old_salario = :new.sal - :new.old_salario
where empno = :old.empno;
end;

 

Compartilhar este post


Link para o post
Compartilhar em outros sites

Meu post acima, basta atribuir direto a uma coluna

Compartilhar este post


Link para o post
Compartilhar em outros sites

Existe a coluna

old_salario 

?

manda o erro do Oracle

Compartilhar este post


Link para o post
Compartilhar em outros sites
Em 29/03/2019 at 10:44, Motta disse:

CREATE OR REPLACE TRIGGER new_salario_emp
BEFORE UPDATE--BEFORE POIS SERÁ ALTERADA UMA COLUNA
   ON emp
   FOR EACH ROW--PARA CADA LINHA
   --
DECLARE

BEGIN
   :NEW.old_salario := :OLD.sal;--ATRIBUI O VALOR ANTERIOR DE SAL A old_salario NAO PODE COMMITAR AQUI
 --
END;

 

Deu certo com esta ação, funcionou corretamente...obrigado

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 asacap1000
      Salve galera estou com uma consulta, e preciso buscar a diferença entre datas, e em alguns casos são vários dias.
      Preciso que nesta consulta ele me retorne em dias, horas limitando a 23h minutos e segundos..
      A consulta que fiz foi essa:
       
      abs(trunc((AK1.DATA_FINAL - AK1.DATA_INICIAL))) AS dias, abs(trunc(24 * (AK1.DATA_FINAL - AK1.DATA_INICIAL))) AS horas, abs(trunc((MOD(MOD(AK1.DATA_FINAL - AK1.DATA_INICIAL, 1) * 24, 1) * 60))) AS minutos, abs(trunc((MOD((MOD(MOD(AK1.DATA_FINAL - AK1.DATA_INICIAL, 1) * 24, 1) * 60), 1) * 60))) AS segundos, ou essa aqui
       
      LPAD(TRUNC(( (AK1.DATA_FINAL - AK1.DATA_INICIAL) * 86400 / 3600)), 3, '0') ||':' || LPAD(TRUNC(MOD( (AK1.DATA_FINAL - AK1.DATA_INICIAL) * 86400 , 3600 ) / 60 ), 2, '0') || ':'|| LPAD(TRUNC(MOD(MOD( (AK1.DATA_FINAL - AK1.DATA_INICIAL) * 86400, 3600 ), 60)), 2, '0') calculado,  e nessa duas consultas ele me traz o total de horas o que complica.
      DIAS  HORAS  MINUTOS  SEGUNDOS  CALCULADO 0 6 1 10 006:01:11 0 0 31 28 000:31:28 0 1 5 8 001:05:09 0 0 41 2 000:41:02 0 4 59 53 004:59:53 0 0 41 6 000:41:06 0 4 59 20 004:59:20 0 0 56 1 000:56:01 0 0 26 31 000:26:31 0 6 10 3 006:10:03 0 0 40 1 000:40:01 0 4 59 53 004:59:53 0 6 3 27 006:03:27 0 6 3 7 006:03:07 0 1 5 57 001:05:58 10 250 28 21 250:28:21 10 250 18 37 250:18:37 0 4 58 42 004:58:43  
       
      Alguem poderia me dar uma força
       
    • 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!
×

Informação importante

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