No trecho abaixo da minha trigger eu retornei null, mas a comando de inserção que lançou a trigger foi executado, não entendi por que isso aconteceu.
O insert que está no trecho do código que antecede o retorno não foi executado, mas o comando gerador da trigger INSERT INTO temp_curso.instrutor (nome, salario) values ('MAIOR SALARIO', 100001); este foi executado, mesmo eu tendo feito o return null
Trecho que retorna nulo:
-- Caso o instrutor inserido receba acima da média, cancele a instrução, ou seja, não permita que a inserção ocorra.
IF (NEW.salario > media_salarial ) THEN
INSERT INTO temp_curso.log_instrutor (informacao) VALUES (NEW.nome || ' NÃO PODE INSERIR. Salario pretendido muito alto: R$ '|| to_char(NEW.salario, 'L99G999G990D99') );
RETURN NULL; -- Eu retornei null aqui mas a inserção foi realizada, não entendi pq, pois eu havia entendido se a gente retorna null, a instrução não seria realizada.
END IF;
Código completo
CREATE OR REPLACE FUNCTION temp_curso.cria_instrutor( )
RETURNS TRIGGER AS $$
DECLARE
media_salarial DECIMAL;
maior_salario DECIMAL;
instrutores_recebem_menos INTEGER DEFAULT 0;
total_instrutores INTEGER DEFAULT 0;
var_salario DECIMAL DEFAULT 0;
percentual DECIMAL (5,2);
BEGIN
SELECT AVG (salario), MAX (salario) INTO media_salarial, maior_salario FROM temp_curso.instrutor
WHERE id <> NEW.id;
-- Caso o instrutor inserido receba acima da média, cancele a instrução, ou seja, não permita que a inserção ocorra.
IF (NEW.salario > media_salarial ) THEN
INSERT INTO temp_curso.log_instrutor (informacao) VALUES (NEW.nome || ' NÃO PODE INSERIR. Salario pretendido muito alto: R$ '|| to_char(NEW.salario, 'L99G999G990D99') );
RETURN NULL; -- Eu retornei null aqui mas a inserção foi realizada, não entendi pq, pois eu havia entendido se a gente retorna null, a instrução não seria realizada.
END IF;
FOR var_salario IN SELECT instrutor.salario FROM temp_curso.instrutor WHERE id <> NEW.id LOOP
total_instrutores := total_instrutores + 1;
IF ( new.salario > var_salario ) THEN
instrutores_recebem_menos := instrutores_recebem_menos + 1 ;
END IF ;
END LOOP;
-- Divisão de inteiro por inteiro, o resultado é inteiro;
percentual := (instrutores_recebem_menos::DECIMAL / total_instrutores::DECIMAL) * 100;
INSERT INTO temp_curso.log_instrutor (informacao )
VALUES ( NEW.nome || ' recebe mais do que ' || percentual || '% da grade de instrutores') ;
-- Caso o instrutor inserido receba mais do que 100% dos instrutores existentes,
-- modifique a inserção para que ele passe a receber o mesmo que o instrutor mais bem pago
IF (percentual = 100) THEN
NEW.salario = maior_salario;
END IF;
RETURN NEW;
END;
$$ language plpgsql;
DROP TRIGGER cria_log_de_instrutores ON temp_curso.instrutor;
CREATE TRIGGER cria_log_de_instrutores
BEFORE INSERT ON temp_curso.instrutor
FOR EACH ROW
EXECUTE PROCEDURE temp_curso.cria_instrutor();
INSERT INTO temp_curso.instrutor (nome, salario) values ('MAIOR SALARIO', 100001);