Olá pessoal, deixa eu deixar os meus 2 centavos na discussão:

na GRANDE maioria das vezes que eu vi situações de "mutating" era uma 
falha na modelagem. Faça uma revisão na modelagem desta estrutura e veja 
se ela está nas formas normais, etc. Porque ao se alterar um registro, 
vc tem setar outros para nulo ?? Não conheço o seu modelo, estou apenas 
abrindo as possibilidades...

Assumindo que o seu modelo está correto ou caso vc não tenha permissão 
ou não possa alterar o modelo:

1) Solução PRAGMA AUTONOMOUS_TRANSACTION na trigger

Eu acho esta solução uma aberração e deveria ser banida do Oracle!!! :)
Primeiro porque eu colocar COMMIT em uma trigger ou até mesmo em uma 
procedure/package é um tiro no pé. Só se deve colocar COMMIT no 
front-end ou em casos batch na rotina mais externa. Qualquer outra opção 
fora disso, é problema certo a longo prazo.

No caso específico da sua trigger, imagine a situação: vc dá o update e 
chama a transação autonoma que seta nulo os campos. Mais a frente, o 
usuário dá rollback ou acontece um outro erro. Qual o resultado: os 
atributos ficaram com nulo e o resto dos registros envolvidos voltaram a 
posição inicial... A sua modelagem irá aceitar isso??

2) Solução aceitável:

- Crie uma tabela temporária CP_TEMP que conterá os registros que vc 
terá que alterar
- Na trigger, apenas insira os registros que comandarão o SET NULL
    INSERT INTO CP_TEMP VALUES ( :NEW.cd_lancam, :NEW.nr_anolot, 
:NEW.cd_lote );
- Crie uma trigger AFTER STATEMENT que irá chamar a procedure MarcaNulo()

- A procedure MarcaNulo() irá consultar a tabela e remover os registros 
desejados:

  begin
     for c1 in (SELECT * FROM CP_TEMP) loop
         UPDATE Cpbaidup
                 SET Set cd_lancam = Null, nr_anolot = Null, cd_lote = null
              Where cd_lancam = c1.cd_lancam And nr_anolot = 
c1.nr_anolot And cd_lote = c1.cd_lote;
     end loop;
  end;

O AFTER STATEMENT também poderá dar erro de mutating caso os registros 
alterados sejam os mesmos que vc acabou de alterar.
Neste caso, vc terá que usar JOBS mas aí a solução é mais complexa.... 
Se não funcionar me fale.

Boa Sorte,
Josir.


[As partes desta mensagem que não continham texto foram removidas]

Responder a