É (ou pelo menos era) conhecido que você não pode usar instruções DML em uma tabela de mutação dentro de um gatilho. Um trecho da documentação do Oracle :
Uma tabela de mutação é uma tabela que está sendo modificada por uma instrução UPDATE, DELETE ou INSERT ou uma tabela que pode ser atualizada pelos efeitos de uma restrição DELETE CASCADE.
A sessão que emitiu a instrução acionadora não pode consultar ou modificar uma tabela mutante. Essa restrição impede que um gatilho veja um conjunto inconsistente de dados.
No entanto, não consigo entender por que esse gatilho de demonstração não está falhando com um erro "tabela de mutação" quando executo um insert into emp
SQL Developer ou SQL * Plus:
CREATE OR REPLACE TRIGGER emp_bri
BEFORE INSERT ON emp
FOR EACH ROW
BEGIN
SELECT max(id) + 1 INTO :NEW.id FROM emp;
UPDATE emp SET salary = 5000;
END emp_bri;
A inserção é concluída com êxito com o próximo id
valor e atualiza todos os emp
registros. Estou usando o Oracle Database 11g Enterprise Edition Release 11.2.0.1.0. Eu li sobre gatilhos compostos, mas a amostra não os utiliza.
fonte
select max(id)
para atribuir números exclusivos. Apenas não. É simplesmente incorreto e não será dimensionado também.Respostas:
Há uma exceção. Quando você define um
before insert
acionador de nível de linha em uma tabela e emite uma únicaINSERT
instrução de linha , otable is mutating
erro não será gerado. Mas se você definir o mesmo tipo de acionador e emitir umaINSERT
instrução de várias linhas , o erro será gerado. Aqui está um exemplo:Aqui está uma
insert
instrução de linha única , que não gera erro de tabela mutante:Aqui está uma instrução de inserção de várias linhas, que irá gerar um erro de tabela mutante:
fonte
ID 132569.1
(ORA-4091 on BEFORE ROW TRIGGER with INSERT .. into SELECT statement
).