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 SILVASS
      Ola,  ja começo pedindo desculpa por mais esse tópico, mas eu realmente não consegui achar nada que me ajudasse.
      Eu preciso criar uma trigger ou qualquer outro procedimento, que me permite incluir todos os dados da tabela principal na tabela histórico a cada alteração/inserção.
       
       
      Está é a trigger que tenho, ela só me retorna o dado alterado/inserido.
          FOR UPDATE, INSERT  AS    BEGIN        SET NOCOUNT ON        INSERT INTO tb_historico  (id_beneficio, habitantes, ano, dh_update)            SELECT id_beneficio, habitantes, ano,  GETDATE()            FROM INSERTED            END
      O dados na minha tabela são os seguintes:
      id     habitante    ano
      1    10000     2019
      2    20000     2019
      3    30000     2019


      Alterei a primeira linha
      id     habitante    ano
      1    50000    2019
      2    20000     2019
      3    30000     2019


      preciso que além do dado alterado, me retorne os dados que não sofreram nenhuma modificação
      id     habitante    ano     
      1    50000    2019
      2    20000     2019
      3    30000     2019


      Hoje o retorno dela seria apenas o dado alterado.
      id     habitante    ano
      1    50000    2019  
    • By fabissilva
      desenvolvi em PL / SQL uma procedure que envia email que está funcionando perfeitamente. Porém foi mudado o servidor de email para Gmail, que requer autenticação e o tipo de conexão é SSL. Poderiam me ajudar com essas alterações?
      A versão do banco de dados é o 11.


      CREATE OR REPLACE PROCEDURE PRC_JUN_SEND_MAIL
      (
      TO_NAME VARCHAR2,
      SUBJECT VARCHAR2,
      MESSAGE VARCHAR2
      )
      IS
      L_BODY VARCHAR2(32767);

      L_MAILHOST VARCHAR2(64) := ''smtp.gmail.com'';
      P_USERNAME_ VARCHAR2(50) := ''admin@jun.net'';
      P_PASSWORD_ VARCHAR2(50) := ''***********'';
      L_DE VARCHAR2(64) := ''Remetente'';
      L_FROM VARCHAR2(64) := ''admin@jun.net'';
      l_port VARCHAR(7) := ''587'';
      L_MAIL_CONN UTL_SMTP.CONNECTION;


      BEGIN
      L_MAIL_CONN := UTL_SMTP.OPEN_CONNECTION(L_MAILHOST,l_port);
      Dbms_Output.Put_Line (''apos conectar'');
      UTL_SMTP.HELO(L_MAIL_CONN, L_MAILHOST);

      Dbms_Output.Put_Line (''hello'');
      UTL_SMTP.COMMAND (L_MAIL_CONN, ''AUTH LOGIN'');
      Dbms_Output.Put_Line (''AUTH LOGIN'');
      UTL_SMTP.COMMAND (L_MAIL_CONN, UTL_RAW.CAST_TO_VARCHAR2(
      UTL_ENCODE.BASE64_ENCODE(UTL_RAW.CAST_TO_RAW(P_USERNAME_))));
      UTL_SMTP.COMMAND (L_MAIL_CONN, UTL_RAW.CAST_TO_VARCHAR2( UTL_ENCODE.BASE64_ENCODE(UTL_RAW.CAST_TO_RAW(P_PASSWORD_))));
      UTL_SMTP.MAIL(L_MAIL_CONN, L_FROM);
      UTL_SMTP.RCPT(L_MAIL_CONN, TO_NAME);

      UTL_SMTP.OPEN_DATA(L_MAIL_CONN);

      UTL_SMTP.WRITE_RAW_DATA( L_MAIL_CONN, UTL_RAW.CAST_TO_RAW(''FROM:'' ||L_DE||''<''|| L_FROM|| ''>'' || UTL_TCP.CRLF));
      UTL_SMTP.WRITE_RAW_DATA( L_MAIL_CONN, UTL_RAW.CAST_TO_RAW(''TO:'' ||TO_NAME||UTL_TCP.CRLF));
      UTL_SMTP.WRITE_RAW_DATA( L_MAIL_CONN, UTL_RAW.CAST_TO_RAW(''SUBJECT:'' ||SUBJECT||UTL_TCP.CRLF));
      UTL_SMTP.WRITE_RAW_DATA( L_MAIL_CONN, UTL_RAW.CAST_TO_RAW(''CONTENT-TYPE: TEXT/HTML; CHARSET=ISO-8859-1''||UTL_TCP.CRLF));
      UTL_SMTP.WRITE_DATA(L_MAIL_CONN, '' ''||UTL_TCP.CRLF);

      UTL_SMTP.WRITE_RAW_DATA(L_MAIL_CONN, UTL_RAW.CAST_TO_RAW(UTL_TCP.CRLF||MESSAGE));

      UTL_SMTP.CLOSE_DATA(L_MAIL_CONN);

      UTL_SMTP.QUIT(L_MAIL_CONN);
      END;
    • By asacap1000
      Galera estou com uma consulta que ainda não consegui entender o porque. gostaria que ela trouxesse em apenas uma linha mas não vem de forma alguma.
       
      SELECT BO.LAGER, BO.ID_OS, K.ID_KLIENT, K.SUCHBEGRIFF CNPJ_CPF, K.NAME, BI.DIV_1 LOTE, BI.DIV_10 DI_DDE, (SELECT DISTINCT DIS.ID_DISPATCHER FROM FISCAL.DOCHD DC, WMS_EADI.DISPATCHER DIS WHERE DC.DOCHD_DOC_ID = BO.NR_NF AND DC.DOCHD_RPS_DESP = DIS.SUCHBEGRIFF) COD_COMISSARIA, (SELECT DISTINCT DIS.BEZ FROM FISCAL.DOCHD DC, WMS_EADI.DISPATCHER DIS WHERE DC.DOCHD_DOC_ID = BO.NR_NF AND DC.DOCHD_RPS_DESP = DIS.SUCHBEGRIFF) COMISSARIA, BO.NR_NF, BO.DATE_BILL, BO.DATE_EMISS, --------ABAIXO OS TIPOS DE SERVIÇOS ONDE ESTÃO OCORRENDO CADA RESULTADO ELE CRIA UMA LINHA---------------- (SELECT SUM(ROUND(OSI.PREIS, 2)) FROM BILL_OS_ITEM OSI WHERE OSI.LAGER = BO.LAGER AND OSI.ID_KLIENT = K.ID_KLIENT AND OSI.ID_OS = BO.ID_OS AND OSI.BILLITE = BI.BILLITE AND OSI.DIV_1 = BI.DIV_1 --AND NVL(OSI.DIV_10, 'x') = NVL(BI.DIV_10, 'x') AND OSI.BILLITE IN (SELECT BLL.BILLITE FROM BILL_ITEM BLL, WERTE WER WHERE BLL.TIPO_FAT = WER.WERT AND WER.WERTE_BER = 'ITENSF' AND WER.WERT = 'ARMAZ')) VLR_ARMAZ, (SELECT SUM(ROUND(OSI.PREIS, 2)) FROM BILL_OS_ITEM OSI WHERE OSI.LAGER = BO.LAGER AND OSI.ID_KLIENT = K.ID_KLIENT AND OSI.ID_OS = BO.ID_OS AND OSI.BILLITE = BI.BILLITE AND OSI.DIV_1 = BI.DIV_1 --AND NVL(OSI.DIV_10, 'x') = NVL(BI.DIV_10, 'x') AND OSI.BILLITE IN (SELECT BLL.BILLITE FROM BILL_ITEM BLL, WERTE WER WHERE BLL.TIPO_FAT = WER.WERT AND WER.WERTE_BER = 'ITENSF' AND WER.WERT = 'GER.RISCO')) VLR_GER_RISCO, (SELECT SUM(ROUND(OSI.PREIS, 2)) FROM BILL_OS_ITEM OSI WHERE OSI.LAGER = BO.LAGER AND OSI.ID_KLIENT = K.ID_KLIENT AND OSI.ID_OS = BO.ID_OS AND OSI.BILLITE = BI.BILLITE AND OSI.DIV_1 = BI.DIV_1 --AND NVL(OSI.DIV_10, 'x') = NVL(BI.DIV_10, 'x') AND OSI.BILLITE IN (SELECT BLL.BILLITE FROM BILL_ITEM BLL, WERTE WER WHERE BLL.TIPO_FAT = WER.WERT AND WER.WERTE_BER = 'ITENSF' AND WER.WERT = 'MOVIMENT')) VLR_MOVIMENTACAO, (SELECT SUM(ROUND(OSI.PREIS, 2)) FROM BILL_OS_ITEM OSI WHERE OSI.LAGER = BO.LAGER AND OSI.ID_KLIENT = K.ID_KLIENT AND OSI.ID_OS = BO.ID_OS AND OSI.BILLITE = BI.BILLITE AND OSI.DIV_1 = BI.DIV_1 --AND NVL(OSI.DIV_10, 'x') = NVL(BI.DIV_10, 'x') AND OSI.BILLITE IN (SELECT BLL.BILLITE FROM BILL_ITEM BLL, WERTE WER WHERE BLL.TIPO_FAT = WER.WERT AND WER.WERTE_BER = 'ITENSF' AND WER.WERT = 'DESUNIT')) VLR_DESUNIT, (SELECT SUM(ROUND(OSI.PREIS, 2)) FROM BILL_OS_ITEM OSI WHERE OSI.LAGER = BO.LAGER AND OSI.ID_KLIENT = K.ID_KLIENT AND OSI.ID_OS = BO.ID_OS AND OSI.BILLITE = BI.BILLITE AND OSI.DIV_1 = BI.DIV_1 --AND NVL(OSI.DIV_10, 'x') = NVL(BI.DIV_10, 'x') AND OSI.BILLITE IN (SELECT BLL.BILLITE FROM BILL_ITEM BLL, WERTE WER WHERE BLL.TIPO_FAT = WER.WERT AND WER.WERTE_BER = 'ITENSF' AND WER.WERT = 'PESAGEM')) VLR_PESAGEM, (SELECT SUM(ROUND(OSI.PREIS, 2)) FROM BILL_OS_ITEM OSI WHERE OSI.LAGER = BO.LAGER AND OSI.ID_KLIENT = K.ID_KLIENT AND OSI.ID_OS = BO.ID_OS AND OSI.BILLITE = BI.BILLITE AND OSI.DIV_1 = BI.DIV_1 --AND NVL(OSI.DIV_10, 'x') = NVL(BI.DIV_10, 'x') AND OSI.BILLITE IN (SELECT BLL.BILLITE FROM BILL_ITEM BLL, WERTE WER WHERE BLL.TIPO_FAT = WER.WERT AND WER.WERTE_BER = 'ITENSF' AND WER.WERT LIKE 'AVERBA%')) VLR_AVERBACAO, (SELECT SUM(ROUND(OSI.PREIS, 2)) FROM BILL_OS_ITEM OSI WHERE OSI.LAGER = BO.LAGER AND OSI.ID_KLIENT = K.ID_KLIENT AND OSI.ID_OS = BO.ID_OS AND OSI.BILLITE = BI.BILLITE AND OSI.BILLITE IN (SELECT BLL.BILLITE FROM BILL_ITEM BLL, WERTE WER WHERE BLL.TIPO_FAT = WER.WERT AND WER.WERTE_BER = 'ITENSF' AND WER.WERT = 'FAT.MINIMO.')) VLR_FAT_MINIMO, (SELECT SUM(ROUND(OSI.PREIS, 2)) FROM BILL_OS_ITEM OSI WHERE OSI.LAGER = BO.LAGER AND OSI.ID_KLIENT = K.ID_KLIENT AND OSI.ID_OS = BO.ID_OS AND OSI.BILLITE = BI.BILLITE AND OSI.DIV_1 = BI.DIV_1 --AND NVL(OSI.DIV_10, 'x') = NVL(BI.DIV_10, 'x') AND OSI.BILLITE IN (SELECT BLL.BILLITE FROM BILL_ITEM BLL, WERTE WER WHERE BLL.TIPO_FAT = WER.WERT AND WER.WERTE_BER = 'ITENSF' AND BLL.BILLITE NOT IN ('21.02', '21.03') AND WER.WERT = 'OUT.SERV.')) VLR_OUTROS_SERV, (SELECT SUM(ROUND(OSI.PREIS, 2)) FROM BILL_OS_ITEM OSI WHERE OSI.LAGER = BO.LAGER AND OSI.ID_KLIENT = K.ID_KLIENT AND OSI.ID_OS = BO.ID_OS AND OSI.BILLITE = BI.BILLITE AND OSI.DIV_1 = BI.DIV_1 --AND NVL(OSI.DIV_10, 'x') = NVL(BI.DIV_10, 'x') AND OSI.BILLITE IN (SELECT BLL.BILLITE FROM BILL_ITEM BLL, WERTE WER WHERE BLL.TIPO_FAT = WER.WERT AND WER.WERTE_BER = 'ITENSF' AND BLL.BILLITE = '21.02' AND WER.WERT = 'OUT.SERV.')) TRANSF_IN, (SELECT SUM(ROUND(OSI.PREIS, 2)) FROM BILL_OS_ITEM OSI WHERE OSI.LAGER = BO.LAGER AND OSI.ID_KLIENT = K.ID_KLIENT AND OSI.ID_OS = BO.ID_OS AND OSI.BILLITE = BI.BILLITE AND OSI.DIV_1 = BI.DIV_1 --AND NVL(OSI.DIV_10, 'x') = NVL(BI.DIV_10, 'x') AND OSI.BILLITE IN (SELECT BLL.BILLITE FROM BILL_ITEM BLL, WERTE WER WHERE BLL.TIPO_FAT = WER.WERT AND WER.WERTE_BER = 'ITENSF' AND BLL.BILLITE = '21.03' AND WER.WERT = 'OUT.SERV.')) TRANSF_OUT FROM BILL_OS BO, BILL_OS_ITEM BI, KLIENTEN K WHERE BO.LAGER = BI.LAGER AND BO.ID_KLIENT = BI.ID_KLIENT AND BO.ID_OS = BI.ID_OS AND BO.LAGER = K.LAGER AND BO.ID_KLIENT = K.ID_KLIENT and k.id_klient = '3099' and BO.NR_NF = '121304' AND BO.STATUS = '90' AND TRUNC(BO.DATE_BILL) BETWEEN '28/08/2019' AND '28/08/2019' GROUP BY BO.LAGER, BO.ID_OS, K.ID_KLIENT, K.SUCHBEGRIFF, K.NAME, BO.DATE_EMISS, BO.NR_NF, BO.DATE_BILL, BI.BILLITE, BI.DIV_1, BI.DIV_10
       
      Alguem consegue identificar neste select porque ele vem assim?
    • By Suporte Risti
      Bom dia, estou iniciando com bando de dados oracle e plsql e estou precisando de uma ajuda para criar um arquivo .bat para nossa empresa em que o usuário consiga apagar os horários do nosso banco de dados, mas não sei como fazer a procedure identificar o dado digitado na variável do .bat
       
      script do .bat
      @echo Off title limpeza de horarios. : inicio cls echo -------------------Informe uma data valida, apenas numeros------------------- echo . echo ------------------------------informe a data--------------------------------- set /p data = echo . echo . sqlplus usuario/senha@intancia @script.sql cls echo . : Fim echo . echo -----------------Horario apagado----------------- echo . pause O script em questão é esse, ele executa uma procedure, ela apaga os horários, o parâmetro da mesma é uma data ex: abaixo.
      set serveroutput on begin sp_apaga_horario('31072019'); end; / exit como eu faço para o dado salvo na variável data seja executado no parâmetro da procedure? não estou conseguindo fazer isso, estou tendo que alterar o script para data que o usuário quer apagar e somente executando o .bat digitando números aleatórios para que ele não trave, não sei como fazer para a mesma identificar esse dado estando em um script diferente.
       
      Quem souber e puder me ajudar ja agradeço desde já.
×

Important Information

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