Pular para o conteúdo
  • Este tópico contém 10 respostas, 4 vozes e foi atualizado pela última vez 9 anos atrás por Avatar de Renato José Correia LimaRenato José Correia Lima.
Visualizando 11 posts - 1 até 11 (de 11 do total)
  • Autor
    Posts
  • #107587
    Avatar de Paulo WerneckPaulo Werneck
    Participante

      Galera, boa tarde…

      Alguém pode me dar uma força com uma trigger, pf…
      Na trigger abaixo eu precisava que quando o botão sn fosse atualizado o usuário ficasse registrado.


      create or replace trigger teste
      after update of sn on testatrigger
      FOR EACH ROW
      begin
      UPDATE testatrigger SET nome = user;
      END;
      /

      vlw, abs!

      #107591
      Avatar de WenderWender
      Participante

        @luckzin

        Seguinte seu código de exemplo segue um exemplo que funcionaria para o que deseja, porém fiquei em uma dúvida, esta tabela terá apenas um registro. A função da trigger sempre será um update sem where?

        De qualquer forma segue abaixo:

        create or replace
        trigger teste
        after update of sn
        on testatrigger
        begin

        update testatrigger
        set nome = sys_context('USERENV','SESSION_USER');

        end;
        /

        Basta substituir o user pela função sys_context passando o parâmetro. Apenas uma observação que se tentar por exemplo utilizar where pelo sn onde terá que utilizar por exemplo:

        referencing new as new old as old
        for each row

        Neste caso irá retornar o erro “ORA-04091: table name is mutating, trigger/function may not see it.”, para resolver este problema terá que utilizar:

        declare
        pragma autonomous_transaction;

        Este irá fazer com que a trigger seja uma transação independente, porém utilize o commit ao final da trigger.

        #107603
        Avatar de Paulo WerneckPaulo Werneck
        Participante

          @Wender

          Obrigado a ajuda, mas acho que ainda estou errando em alguma coisa.

          rodei a trigger da seguinte forma:

          CREATE OR REPLACE TRIGGER TESTE
          AFTER UPDATE OF SN ON TESTATRIGGER
          REFERENCING NEW AS NEW OLD AS OLD
          FOR EACH ROW
          DECLARE
          PRAGMA AUTONOMOUS_TRANSACTION;
          BEGIN
          UPDATE TESTATRIGGER SET NOME = sys_context('USERENV','SESSION_USER');
          END;
          /

          Depois eu tento realizar o seguinte update:
          UPDATE TESTATRIGGER SET SN = 'S' WHERE COD = 1;

          E me gera o seguinte erro:
          ORA-00060: deadlock detected while waiting for resource
          ORA-06512: at “DBAMV.TESTE”, line 4
          ORA-04088: error during execution of trigger ‘DBAMV.TESTE’
          00060. 00000 – “deadlock detected while waiting for resource”
          *Cause: Transactions deadlocked one another while waiting for resources.
          *Action: Look at the trace file to see the transactions and resources
          involved. Retry if necessary.

          #107604
          Avatar de WenderWender
          Participante

            @luckzin

            A forma que esta sendo feito o update não precisa utilizar:
            referencing new as new old as old
            for each row

            e nem a declaração

            declare
            pragma autonomous_transaction;

            Apenas crie a trigger da seguinte maneira:

            create or replace
            trigger teste
            after update of sn
            on testatrigger
            begin

            update testatrigger
            set nome = sys_context('USERENV','SESSION_USER');

            end;
            /

            Ocorre que quando utiliza for each row ele irá tentar fazer a ação no begin para os registros, como um update disparou a trigger, a sessão está com este registro aberto.

            #107605
            Avatar de rmanrman
            Participante

              @luckzin

              Faltou o COMMIT após o UPDATE.

              #107606
              Avatar de Paulo WerneckPaulo Werneck
              Participante

                @Wender

                Mas como eu faço pra atualizar pela trigger apenas o campo com o COD = 1 que foi definido no update?

                #107607
                Avatar de WenderWender
                Participante

                  @rman

                  Neste caso não é necessário de commit dentro do corpo da trigger a não ser que seja utilizado
                  declare
                  pragma autonomous_transaction;

                  Então quem faz o commit? Quando uma sessão executar um comando update a mesma também irá disparar a trigger, logo quando esta sessão fizer o commit automaticamente a trigger será feito o commit, pois faz parte da transacação.

                  http://bennettgolfcars.ca/upfile/manufile/20130125_22_25_06.pdf

                  Pagina 457 do livro OCA Oracle Database 11g : Administration I Exam Guide.

                  Porém colocar o commit dentro do bloco begin da trigger não irá ocorrer qualquer erro, é mais uma forma de organização/construção dos códigos PL/SQL.
                  🙂

                  #107608
                  Avatar de WenderWender
                  Participante

                    @luckzin

                    Deixa entender, você quer que a trigger seja disparada apenas quando cod=1 ?

                    #107609
                    Avatar de Paulo WerneckPaulo Werneck
                    Participante

                      @Wender

                      Quero que ela seja disparada apenas para o registro que eu fizer o update.
                      no exemplo tava usando cod=1, então queria que disparasse para esse registro.
                      Se fosse cod=2 dispararia para o registro que faz referencia ao código 2.

                      UPDATE TESTATRIGGER SET SN = 'S' WHERE COD = 1;

                      #107610
                      Avatar de rmanrman
                      Participante

                        @Wender

                        Exatamente, se trabalhar com autonomous_transaction é necessário o uso do COMMIT, caso contrario a transação ficará em aberto, isso causou o DEADLOCK.

                        Eu não recomendo o uso do autonomous_transaction.Prefiro trabalhar como você apresentou, deixar a transação original fazer o COMMIT/ROLLBACK.

                        #107878
                        Avatar de Renato José Correia LimaRenato José Correia Lima
                        Participante

                          E porque não tratar no BEFORE e depois atribuir o valor diretamente ao campo.

                          CREATE OR REPLACE TRIGGER teste
                          BEFORE UPDATE OF sn
                          ON testatrigger
                          FOR EACH ROW
                          BEGIN
                          IF NVL (:OLD.sn, 'S') NVL (:NEW.sn, 'S')
                          THEN
                          :NEW.nome := USER;
                          END IF;
                          END;
                          /

                          Att.

                        Visualizando 11 posts - 1 até 11 (de 11 do total)
                        • Você deve fazer login para responder a este tópico.
                        plugins premium WordPress