0
The database simulates a traffic department (similar to the DMV). I would like to implement a resource in which: once a new one has been registered multa
, the system would automatically add the points of this new fine to the cnh
of the driver.
However, the table multa
does not communicate directly with the table cnh
. multa
is referenced in the table registro
by a FK, and registro
has a table FK cnh
.
My tables are arranged this way:
CREATE TABLE multa (
numero_auto INT NOT NULL, -- tabela de auto não é importante nesse caso
pontuacao INT NOT NULL,
validade DATE NOT NULL,
situacao_pgto VARCHAR(1),
gravidade VARCHAR(10),
CONSTRAINT pk_multa PRIMARY KEY (numero_auto),
CONSTRAINT fk_auto FOREIGN KEY (numero_auto) REFERENCES auto(numero_auto)
ON DELETE CASCADE ON UPDATE CASCADE
);
CREATE TABLE registro (
numero_auto INT NOT NULL, -- fk de multa
placa VARCHAR(7), -- tabela de veículo não é importante para este caso
numero_cnh INT, -- fk de cnh
CONSTRAINT pk_registro PRIMARY KEY (placa, numero_cnh),
CONSTRAINT fk_auto FOREIGN KEY (numero auto) REFERENCES multa(numero_auto)
ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT fk_veiculo FOREIGN KEY (placa) REFERENCES veiculo(placa)
ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT fk_cnh FOREIGN KEY (numero_cnh) REFERENCES cnh(numero_cnh)
ON DELETE NO ACTION ON UPDATE CASCADE
);
CREATE TABLE cnh (
numero_cnh SERIAL,
validade DATE NOT NULL,
pontos INT,
data_emissao DATE NOT NULL,
categoria VARCHAR(1)
cpf VARCHAR(11) NOT NULL, -- tabela de usuario não é importante para este caso
CONSTRAINT pk_cnh PRIMARY KEY (numero_cnh),
CONSTRAINT uq_numero_cnh UNIQUE (cpf, numero_cnh),
CONSTRAINT fk_usuario FOREIGN KEY(cpf) REFERENCES usuario(cpf)
ON DELETE CASCADE ON UPDATE CASCADE
);
What I wish to do is the following: Whenever a new one is added multa
, the system shall verify to which cnh
that fine belongs and change the column "points" of that cnh
to add to this value the score of the new multa
.
Until then I had tried to solve this problem with a TRIGGER
. Although it wasn’t working, this was the code:
CREATE FUNCTION add_pontos_cnh() RETURNS trigger AS $add_pontos$
BEGIN
IF TG_OP = 'UPDATE' THEN -- caso a pontuação não se altere não é necessário alterar cnh
IF OLD.pontuacao <> NEW.pontuacao THEN
UPDATE cnh SET pontos = cnh.pontos - OLD.pontuacao + NEW.pontuacao -- retira-se a pontuacao antiga e soma-se a nova
FROM multa JOIN registro USING (numero_auto)
WHERE cnh.numero_cnh = registro.numero_cnh
AND NEW.numero_auto = multa.numero_auto;
RETURN NEW;
END IF;
ELSIF TG_OP = 'INSERT' THEN
UPDATE cnh SET pontos = cnh.pontos + NEW.pontuacao
FROM multa JOIN registro USING (numero_auto)
WHERE cnh.numero_cnh = registro.numero_cnh
AND NEW.numero_auto = multa.numero_auto;
RETURN NEW;
END IF;
END;
$add_pontos$ LANGUAGE plpgsql;
CREATE TRIGGER add_pontos AFTER INSERT OR UPDATE ON multa
FOR EACH ROW EXECUTE PROCEDURE add_pontos_cnh();
The code compiles without errors, but when giving INSERT
in fine, the value of "points" in cnh
does not change.
The problem is that you are using the JOIN clause in the UPDATE command. See the documentation and do not use the JOIN expression, use only the FROM clause and the condition.
– anonimo
So, but how will I use only FROM and a condition being that fine and CNH are not related? How would I write the condition?
– Lucas Santana