Jump to content
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;

 

Share this post


Link to post
Share on other 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;

Share this post


Link to post
Share on other 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.

 

Share this post


Link to post
Share on other 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?

 

Share this post


Link to post
Share on other 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

Share this post


Link to post
Share on other 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

Share this post


Link to post
Share on other 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;

 

Share this post


Link to post
Share on other 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;

 

Share this post


Link to post
Share on other 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;

 

Share this post


Link to post
Share on other 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;

 

Share this post


Link to post
Share on other sites

Meu post acima, basta atribuir direto a uma coluna

Share this post


Link to post
Share on other sites

Existe a coluna

old_salario 

?

manda o erro do Oracle

Share this post


Link to post
Share on other 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

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 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!
    • By msr1990
      ... o procedimento deverá atualizar os campos "quantmsgnaolidas" e "quantamigosativos", existentes na tabela de usuários. Cada um destes campos está relacionado de forma indireta as tabelas de mensagem e amigos.
       
      Deverá ser postado um arquivo em formato TXT ou DOC contendo o código em ORACLE do procedimento criado.
       
      Alguém pode me ajudar por favor? :)

    • By asacap1000
      Salve galera estou com um problema em uma consulta no banco de dados.
      Preciso trazer um xml de um campo porém tem alguns lançamentos que estão com mais de 4000 caracteres, estou usando para a pesquisa o seguinte select
       
      SELECT ID_WS_GATEWAY, ID_WS_CONFIG, STATUS, ERRCODE, ERRMSG, FOLDER, FILENAME, DATE_IN, DATE_ON, SITE, WS, DBMS_LOB.SUBSTR(T.XMLDATA.getClobVal(),4000,1) XMLDATA, DIRECTION FROM WS_GATEWAY T Tem alguma outra forma de buscar uma quantidade maior neste campo?
       
       
    • By devenr
      E ai pessoal!
       
      Estou desenvolvendo uma procedure e estou com dificuldade para validar um campo.
      É seguinte, preciso verificar se o campo contem um registro, se contem, realiza o update concatenando com o registro de entrada e se não conter registro, apenas faça o update com o registro de entrada.
      Obs: Esse campo é separado por virgula.
       
      Segue o meu código:
      CREATE OR REPLACE PROCEDURE SP_VINCULO (     P_COD_MATRIZ IN TB_EDIEXT_PERFIL.COD_MATRIZ%TYPE,     P_CONCIL IN TB_EDIEXT_PERFIL.CONCIL%TYPE,     P_ID_MBX IN TB_EDIEXT_PERFIL_MBX.ID_MBX%TYPE,     P_ID_CONCIL INT,     P_DIR_DEST VARCHAR2,     P_PROTOCOLO VARCHAR2 ) IS     V_EC TB_EDIEXT_PERFIL.CONCIL%TYPE;     V_REG_CONCIL NUMBER(1);     V_CONCIL_EC VARCHAR(10);     CONTEM_EC EXCEPTION;     CONTEM_REG EXCEPTION;          CURSOR VERIFICA_EC IS     SELECT P_CONCIL     FROM TB_EDIEXT_PERFIL     WHERE CONCIL = 'EC';              CURSOR VERIFICA_CONCIL IS     SELECT CONCIL     FROM TB_EDIEXT_PERFIL     WHERE CONCIL = 'EC';      BEGIN     INSERT INTO TB_EDIEXT_PERFIL_MBX          VALUES      (PERFIL_MBX.nextval, (SELECT ID FROM TB_EDIEXT_PERFIL WHERE COD_MATRIZ = P_COD_MATRIZ),      (SELECT ID FROM TB_EDIEXT_MBX WHERE MBX = 'MB'||P_CONCIL));          IF P_PROTOCOLO = 'SFTP' THEN         INSERT INTO TB_EDIEXT_PERFIL_SFTP                 VALUES          (PERFIL_SFTP.nextval, (SELECT ID FROM TB_EDIEXT_PERFIL WHERE COD_MATRIZ = P_COD_MATRIZ),                                                                                   P_ID_CONCIL,                                                                                    P_DIR_DEST);         UPDATE TB_EDIEXT_PERFIL          SET SFTP = 1          WHERE COD_MATRIZ = P_COD_MATRIZ;          ELSE         INSERT INTO TB_EDIEXT_PERFIL_CD                 VALUES          (PERFIL_CD.nextval, (SELECT ID FROM TB_EDIEXT_PERFIL WHERE COD_MATRIZ = P_COD_MATRIZ),                                                                                 P_ID_CONCIL,                                                                                  P_DIR_DEST,                                                                                 NULL);         UPDATE TB_EDIEXT_PERFIL          SET CD = 1          WHERE COD_MATRIZ = P_COD_MATRIZ;     END IF;               OPEN VERIFICA_EC;         FETCH VERIFICA_EC INTO V_EC;              IF P_CONCIL = 'EC' THEN         RAISE CONTEM_EC;     END IF;           SELECT CASE WHEN EXISTS (         SELECT CONCIL FROM TB_EDIEXT_PERFIL WHERE CONCIL LIKE P_CONCIL)             THEN 1             ELSE 0     END AS VERIFICA_CONC INTO V_REG_CONCIL     FROM DUAL;          IF V_REG_CONCIL = 1 THEN         RAISE CONTEM_REG;     END IF;    OPEN VERIFICA_CONCIL;     FETCH VERIFICA_CONCIL INTO V_CONCIL_EC;      -- NESTA ETAPA ESTOU VERIFICANDO SE O CAMPO É = 'EC', SE FOR ELE FAZ APENAS O UPDATE SUBSTITUINDO PARA O P_CONCIL DE ENTRADA     IF V_CONCIL_EC = 'EC' THEN         UPDATE TB_EDIEXT_PERFIL         SET CONCIL = P_CONCIL         WHERE COD_MATRIZ = P_COD_MATRIZ; -- AQUI DEVERIA FAZER O UPDATE CONCATENANDO O P_CONCIL, MAS NÃO ESTÁ FUNCIONANDO.     ELSE          UPDATE TB_EDIEXT_PERFIL         SET CONCIL = (SELECT CONCIL FROM TB_EDIEXT_PERFIL          WHERE COD_MATRIZ = P_COD_MATRIZ)||','||P_CONCIL          WHERE COD_MATRIZ = P_COD_MATRIZ AND ROWNUM = 1;     END IF;                      EXCEPTION         WHEN CONTEM_EC             THEN DBMS_OUTPUT.PUT_LINE('NÃO É PERMITIDO VINCULAR '||V_EC);         WHEN CONTEM_REG             THEN DBMS_OUTPUT.PUT_LINE('ERRO! A matriz ja possui vinculo com a conciliadora.');       CLOSE VERIFICA_EC; CLOSE VERIFICA_CONCIL; END; /  
      O que está ocorrendo é o seguinte, ele está substituindo o campo CONCIL sempre com o parâmetro de entrada P_CONCIL e a concatenação não está funcionando.
       
      Alguém sabe o porque? 
       
      Obrigado desde já!
×

Important Information

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