Pular para o conteúdo
  • Este tópico contém 6 respostas, 5 vozes e foi atualizado pela última vez 17 anos, 9 meses atrás por Marcio68Almeida.
Visualizando 7 posts - 1 até 7 (de 7 do total)
  • Autor
    Posts
  • #81857
    drhoffman
    Participante

      Boas pessoal , Tou de volta de um projecto para a faculdade e tou aqui com uma duvida! é o seguinte! Uma factura pode ter associados diversos pagamentos! eu quando estou a introduzir um pagamento quero que ele me actualize o total na factura! eu pela minha logica devia fazer um after insert mas quando o faço obtenho este erro quando insiro um pagamento

      “One error saving changes to table “SYSDBA”.”PAGAMENTOS”:
      Row 6: ORA-04091: table SYSDBA.PAGAMENTOS is mutating, trigger/function may not see it
      ORA-06512: at “SYSDBA.PAGAMENTOS_T1″, line 5
      ORA-04088: error during execution of trigger ‘SYSDBA.PAGAMENTOS_T1’
      ORA-06512: at line 1”

      Pondo o before ele funciona mas ele vai fazer a soma de todos os pagamentos anteriores referente á factura mas nao soma o ultimo valor do pagamento , ou seja , o do pagamento que esta a ser inserido quando o trigger é despolotado! eu acho que com um after resolvia o problema
      quando insiro um pagamento ele da me o erro descrito acima e nao sei o que fazer mais!

      O Trigger é o seguinte:

      create or replace
      trigger “PAGAMENTOS_T1”
      before
      insert on “PAGAMENTOS”
      for each row
      begin
      DECLARE
      v_valor number;
      BEGIN
      SELECT nvl(sum(valor),0)
      INTO v_valor
      FROM PAGAMENTOS
      WHERE id_factura = :new.id_factura;
      UPDATE facturas
      SET valor_factura = v_valor;
      END;
      END;

      Alguem me consegue dar uma ajudinha?

      Obrigado 🙂

      #81858
      drhoffman
      Participante

        Outro problema que tenho é que o trigger actualiza-me todas as facturas e nao apenas a factura em que o pagamento esta a ser inserido! deve ter a ver com esta linha

        WHERE id_factura = :new.id_factura;

        o meu raciocionio foi , que ele me selecionasse a factura que foi introduzida no pagamento!

        #81864
        DanielB
        Participante

          pq nao escrive o trigger assim

          create or replace
          trigger “PAGAMENTOS_T1”
          before
          insert on “PAGAMENTOS”
          for each row
          BEGIN
          UPDATE facturas
          SET valor_factura = nvl(:new.valor,0) + nvl(valor_factura,0)
          WHERE id_factura = :new.id_factura;
          END;

          #81866
          Avatar photoLeonardo Litz
          Participante

            Ola… o erro de trigger mutante ocorre pois vc esta tentando efetuar uma operacao em uma tabela que esta sendo alterada no momento, neste caso o oracle interfere dizendo que nao ha garantia de que o dado retornado pode nao esta correto, no post anterior ja resolvera seu problema. Oque vc tb pode fazer eh colocar um pragma na trigger para que o oracle nao considere esta situacao.

            Coloque esta linha apos o begin da trigger

            Pragma Autonomous_Transaction;

            #81872
            andrezavan
            Participante

              Olá… também estou com o mesmo problema. No meu caso eu tenho uma trigger que chama uma procedure quando essa trigger é disparada, a processedure realizar a operacao na mesma tabela que esta o evento da trigger. Tentei colocar o Pragma Autonomous_Transaction porém o Developer diz que nao possivel especifiar o pragma.

              Desde já agradeço.

              André Zavan

              [quote=”Litz”:y99gzmlz]Ola… o erro de trigger mutante ocorre pois vc esta tentando efetuar uma operacao em uma tabela que esta sendo alterada no momento, neste caso o oracle interfere dizendo que nao ha garantia de que o dado retornado pode nao esta correto, no post anterior ja resolvera seu problema. Oque vc tb pode fazer eh colocar um pragma na trigger para que o oracle nao considere esta situacao.

              Coloque esta linha apos o begin da trigger

              Pragma Autonomous_Transaction;[/quote]

              #81873
              drhoffman
              Participante

                boas pessoal! consegui resolver o problema como voces me disseram mas surgiu me outro! eu nem com o pragma consigo que ele me deixe fazer o after insert! agora tenho este erro

                “One error saving changes to table “SYSDBA”.”PAGAMENTOS”:
                Row 5: ORA-06519: active autonomous transaction detected and rolled back
                ORA-06512: at “SYSDBA.TRG_ACTUALIZA_FACTURA”, line 11
                ORA-04088: error during execution of trigger ‘SYSDBA.TRG_ACTUALIZA_FACTURA’
                ORA-06512: at line 1″

                mas de qualquer maneira o trigger ta a funciona e fica aqui , mas tenho outro problema. eu criei outro tigger que dependendo do tipo de quota do socio ele atribui um valor no pagamento

                o trigger e este

                create or replace TRIGGER TRG_ATRIBUI_VALOR
                BEFORE INSERT ON PAGAMENTOS
                FOR EACH ROW
                DECLARE
                v_valor PAGAMENTOS.valor%TYPE;
                v_tipo_socio tipos_socio.id_tipo_socio% TYPE;
                BEGIN
                SELECT distinct tq.valor_quota
                into v_valor_quota
                from tipos_quota tq,socios s
                where s.id_tipo_quota=tq.id_tipo_quota
                and s.id_pessoa=:new.id_pessoa;
                :NEW.valor := v_valor_quota;
                END;

                o trigger ta a funcionar mas se tiver os dois triggers a funcionar ao mesmo tempo ele introduz me o pagamento de acordo com o que eu quero mas nao me incrementa o valor na factura! eu acho que o problema é por serem ambos before insert mas o problema é que mesmo com o pragma nao consigo resolver esta situacao! alguem tem sugestoes? o que eu quero e que quando introduzo um pagamento ele automaticamente introduz o pagamento e depois acumula na factura! se eu puser apenas um deles a trabalhar no sistema eles funcionam sem problemas mas quando estão os dois ele so me introduz o pagamento e nao me actualiza a factura! obrigado.

                Aqui fica o script

                create or replace
                trigger “TRG_ACTUALIZA_FACTURA”
                before
                insert on “PAGAMENTOS”
                for each row
                DECLARE
                v_valor number;
                BEGIN
                SELECT SUM(valor)
                INTO v_valor
                FROM PAGAMENTOS;
                UPDATE facturas
                SET valor_factura = :NEW.Valor + v_valor
                WHERE id_factura = :NEW.id_factura;
                END;

                #81883
                Marcio68Almeida
                Participante

                  Trigger é uma ferramenta maravilhosa, mas creio que você está entrando em um terreno perigoso, pois estou percebendo que muito em breve você terá triggers encadeadas, isso costuma gerar um travamento no sistema e é muito difícil de encontrar o erro quando isso acontece, pois não é fácil identificar em que ponto do processo travou…
                  Talvez seja mais interessante fazer as atualizações em processos batch e views informando on-line os valores atualizados.
                  Aproveite para verificar se nesses seus testes você não deixou processos pendentes :
                  Select s.sid, s.serial#, o.owner, s.lockwait, s.username, s.osuser, s.terminal, s.status, l.id2, decode (NVL (l.id2, 0), 0, o.object_name, 'Trans-' || to_char (l.id1)) object_name, decode (NVL (l.type, '.'), 'BL', 'Buffer hash table instance', 'CF', 'Control file schema global enqueue', 'CU', 'Cursor bind', 'CI', 'Cross-instance function invocation instance','DF', 'Data file instance', 'JQ', 'Job queue', 'DL', 'Direct loader parallel index create', 'TX', 'Transaction enqueue', 'UL', 'User supplied', 'DM', 'Mount/startup db primary/secondary instance', 'DR', 'Distributed recovery process', 'DX', 'Distributed transaction entry', 'TM', 'DML enqueue', l.type) type, decode (NVL (l.lmode, 0), 0, '--Waiting--', 1, 'Null', 2, 'Row Share', 3, 'Row Excl', 4, 'Share', 5, 'Sha Row Exc', 6, 'Exclusive', 'Other') "Lock Mode", decode (NVL (l.request, 0), 0, ' - ', 1, 'Null', 2, 'Row Share', 3, 'Row Excl', 4, 'Share', 5, 'Sha Row Exc', 6, 'Exclusive', 'Other') "Req Mode"
                  From gv$lock l, gv$session s, dba_objects o
                  Where s.sid = l.sid (+)
                  and l.id1 = o.object_id (+)
                  and s.username is not null
                  Order by l.id2, s.sid

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