How to do an automatic UPDATE after an INSERT in tables without FK in Postgresql

Asked

Viewed 170 times

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.

Follow the schematic of the problem: inserir a descrição da imagem aqui

  • 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.

  • 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?

1 answer

0


Do as the example below:

UPDATE cnh SET pontos = cnh.pontos - OLD.pontuacao + NEW.pontuacao
                   FROM multa, registro
                   WHERE cnh.numero_cnh = registro.numero_cnh
                     AND multa.numero_auto = registro.numero_auto
                     AND NEW.numero_auto = multa.numero_auto;

Browser other questions tagged

You are not signed in. Login or sign up in order to post.