2
respostas

Rollback não ocorre com erro na trigger

O instrutor é inserido na tabela, assim como os logs na tabela de logs, mesmo quando há erro na função, como na função abaixo (não há campo 'teste' na tabela 'log_instrutores'). É como se o erro fosse ignorado. Isso ocorre mesmo quando a trigger é definida before insert. Essa questão já foi levantada no forum, mas não houve solução.

create or replace function valida_instrutores() returns trigger as $$

    declare
        id_instrutor_inserido integer;
        media_salarial decimal;
        instrutores_recebem_menos integer default 0;
        total_instrutores integer default 0;
        salario decimal;
        percentual decimal;
        
    begin
    
        select avg(instrutor.salario) into media_salarial from instrutor where id <> new.id;
        if new.salario > max(instrutor.salario) from instrutor then
            insert into log_instrutores (informacao) values (new.nome ||' não incluído por ganhar acima de todos os colaboradores');
            return null;
        end if;
        
        for salario in select instrutor.salario from instrutor where id <> new.id loop
            total_instrutores := total_instrutores + 1;
            if new.salario > salario then
                instrutores_recebem_menos := instrutores_recebem_menos + 1;
            end if;
        end loop;
        
        percentual = instrutores_recebem_menos::decimal / total_instrutores::decimal * 100;
        
        insert into log_instrutores (informacao, teste) values (new.nome||' recebe mais do que '|| percentual || '% da grade de instrutores', '');
        return new;
        
    exception
        when undefined_column then
            return new;
            
    end
$$ language plpgsql;

create trigger valida_instrutor after insert on instrutor
for each row execute function valida_instrutores();

insert into instrutor (nome, salario) values ('S', 500);

select * from instrutor;

select * from log_instrutores;
2 respostas

Oii, Jorge! Tudo bem?

Desculpa pela demora em responder a você.

É exatamente o que deve acontecer, o Rollback garante que, em caso de erro durante uma transação, todas as alterações feitas até o ponto de erro sejam revertidas, retornando o banco de dados ao estado original. E conforme podemos constar na documentação, quando há erro o processamento da parte do statements é abandonada e o controle passa para EXCEPTION.

E caso você se lembre, a intenção desde o começo da aula era esse. Ou seja, caso ocorre algum erro nos INSERT do script, não era para modificar.

Você pode conferir o momento dessa explicação no minuto 5:38 do vídeo e também na documentação que o professor utiliza, segue o link:

A página pode abrir em Inglês, caso não se sinta confortável com o idioma, clique com o botão direito do mouse em qualquer canto da página e escolha a opção "Traduzir para o português".

Espero ter esclarecido a sua dúvida. Caso contrário, fico à disposição para te auxiliar.

Bons estudos!

Acho que não ficou compreendido. É exatamente o que deve acontecer, porém não é o que acontece. A alteração é realizada apesar do erro forçado na transição. O erro é ignorado e a inserção é incluída na base, conforme dito.