Contornar problema com tabela mutante

Dúvidas, dicas e truques de PL/SQL. Aqui também vão assuntos relacionados a pacotes, triggers, funções, Java-Stored Procedures, etc
Responder
jks1903
Rank: DBA Júnior
Rank: DBA Júnior
Mensagens: 188
Registrado em: Qui, 04 Fev 2010 8:08 am

Pessoal, estou enfrentando um problema em triggers que acusam que a tabela é mutante.
Estive verificando em alguns outros tópicos referentes a isso aqui no fórum, mas não encontrei um caso semelhante ao que estou precisando agora.

Possuimos uma tabela de valores que de tempos em tempos sofre um reajuste, baseado em um percentual informado. Porém, esse reajuste não pode ser maior que determinada porcentagem e devido a isso criamos uma trigger que testa o percentual de aumento do item em relação ao já existente. Caso o valor seja maior, o mesmo é corrigido para o máximo permitido, caso contrário apenas insere o valor novo.
O problema é que para realizar esse cálculo eu preciso fazer um SELECT na própria tabela da trigger, o que acaba causando tabela mutante. Tentei criar a trigger em uma view, mas percebi que não é possível alterar os valores :new.campo para esse tipo de trigger.

Alguém teria alguma idéia de como contornar isso?

E aproveitando o tópico, apenas um esclarecimento.
Criei uma tabela e triger de teste para testar a lógica que iria aplicar na produção. Seguem as mesmas:

Selecionar tudo

CREATE TABLE teste(
  cd_item NUMBER,
  dt_item DATE,
  vl_item FLOAT
)


CREATE OR REPLACE TRIGGER trg_teste
BEFORE INSERT
ON teste
FOR EACH ROW
DECLARE vlrCorreto NUMBER;
        numLinhas NUMBER;
BEGIN
     SELECT Count(*) INTO numLinhas
        FROM teste WHERE cd_item = :NEW.cd_item;

     IF (numLinhas>0) THEN
     BEGIN
          SELECT (vl_item + (vl_item*0.0769)) vlr INTO vlrCorreto
            FROM teste
            WHERE cd_item = :NEW.cd_item
                  AND dt_item = (SELECT Max(dt_item)
                                   FROM teste
                                   WHERE cd_item = :NEW.cd_item);
          IF (:NEW.vl_item > vlrCorreto) THEN
          BEGIN
               :NEW.vl_item := vlrCorreto;
          END;
          END IF;
    END;
    END IF;
END;

Como podem ver, essa triger também realiza um SELECT na prórpia tabela da trigger. Esse caso não deveria acusar tabela mutante também?
Estou conseguindo realizar inserts em TESTE sem problemas.

Obrigado.
DanielNN
Moderador
Moderador
Mensagens: 641
Registrado em: Seg, 03 Set 2007 3:26 pm
Localização: Fortaleza - CE
att,

Daniel N.N.

Existem alguns tópicos sobre isto aqui no forum:

http://glufke.net/oracle/viewtopic.php? ... MOUS#p4344
http://glufke.net/oracle/viewtopic.php? ... OUS#p33091
http://glufke.net/oracle/viewtopic.php? ... OUS#p32778

Agora o porque no seu teste não deu erro. Olhando de cara não identifiquei.
diegolenhardt
Moderador
Moderador
Mensagens: 1177
Registrado em: Qui, 15 Out 2009 10:28 am
Localização: Recife

provavelmente no seu teste, não chegou a entrar no IF...

não fazendo o select , não dá erro de tabela mutante...
DanielNN
Moderador
Moderador
Mensagens: 641
Registrado em: Seg, 03 Set 2007 3:26 pm
Localização: Fortaleza - CE
att,

Daniel N.N.

Selecionar tudo

SELECT Count(*) INTO numLinhas
        FROM teste WHERE cd_item = :NEW.cd_item;
Porém o valor do teste é setado pelo select da mesma tabela.
Mais tarde tento ver este problema.
jks1903
Rank: DBA Júnior
Rank: DBA Júnior
Mensagens: 188
Registrado em: Qui, 04 Fev 2010 8:08 am

Blza, consegui resolver o problema com o PRAGMA AUTONOMOUS_TRANSACTION. Funcionou perfeito.
Somente não consegui identificar o mistério do teste, pois até onde sei deveria acusar o mutating.

Se alguém descobrir o porque funcionou o teste posta aew, rsrs.

Vlw.
DanielNN
Moderador
Moderador
Mensagens: 641
Registrado em: Seg, 03 Set 2007 3:26 pm
Localização: Fortaleza - CE
att,

Daniel N.N.

Rapaz.......
estou achando mutante é esse teste aí....
Fiz aqui e realmente ela não dá problema nenhum.
Fui tentar causar o erro, não consegui. Consegui fazer tudo dentro da trigger(select, update, delete) tudo funcionava perfeitamente sem qualquer problema;
Insert dava problema de recursividade, pois ficava inserindo em loop. Mas nada de mutante.
Criei também Primary Key para ela, mas não consegui deixar a maldita trigger mutante.

Estou sem entender por enquanto. Ainda volto a olhar isto.
Responder
  • Informação
  • Quem está online

    Usuários navegando neste fórum: Nenhum usuário registrado e 20 visitantes