Oracle
 sql >> Base de Dados >  >> RDS >> Oracle

Como evitar o erro ORA-04091 em um gatilho


Você pode fazer com que o gatilho em A faça algo para alertar o gatilho em B que ele não precisa disparar. Existem vários desejos para configurar algum estado para uma sessão. A abordagem mais simples possível seria fazer algo como criar um pacote com uma variável booleana bypass_checks_on_b que você definiu como TRUE antes de fazer o UPDATE em A, defina como FALSE uma vez que o UPDATE complete, e então verifique o estado desta variável em seu trigger em B antes de fazer suas validações. Você também pode fazer algo semelhante com uma tabela temporária ou um contexto, em vez de usar um pacote. Com menos eficiência, você poderia analisar a pilha de chamadas dentro de seu gatilho em B para ver se o gatilho em A está na pilha de chamadas, mas isso tenderia a ser bastante feio.

Eu seria muito cauteloso com toda essa arquitetura, no entanto. Quando você descobre que tem gatilhos em A que fazem com que gatilhos em B sejam acionados que gostariam de consultar A, é quase sempre o caso de você ter colocado muita lógica nos gatilhos e que seria muito melhor se mover essa lógica em uma camada de procedimento armazenado que pode ser chamada em vez dos aplicativos fazendo inserções ou atualizações diretas. Quando você coloca muita lógica em gatilhos, você acaba com um sistema que é muito difícil de entender porque não é óbvio olhando para o código do aplicativo que tipo de efeitos colaterais várias declarações têm. E você acaba com um código muito stateful, onde você tem muitos caminhos por meio de um único pedaço de código, dependendo do chamador. Isso quase certamente significa que haverá estados que você não testa ou não pensa onde descobrirá que seu código faz algo inesperado. Entre ter uma tonelada de estado e ter uma base de código com uma tonelada de efeitos colaterais, você pode construir rapidamente uma base de código que é essencialmente insustentável.