Postgres更新触发器

时间:2020-03-10 13:59:56

标签: postgresql

我在postgresql中的触发函数有问题。 这是我的简单代码。

CREATE TABLE specie
(specie_id INT PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
nome_comune TEXT UNIQUE,
nome_scientifico TEXT UNIQUE);

CREATE TABLE rilevatore
(rilevatore_id INT PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
nome_cognome TEXT);

CREATE TABLE evento_investimento
(evento_id INT PRIMARY KEY GENERATED BY DEFAULT AS IDENTITY,
data DATE,
ora TIME WITHOUT TIME ZONE,
rilevatore_id INT REFERENCES rilevatore (rilevatore_id),
specie_id INT REFERENCES specie(specie_id));

CREATE VIEW inserimento_dati_vista AS
SELECT row_number() OVER ()::integer AS gid,
evento_investimento.ora,
evento_investimento.data,
rilevatore.nome_cognome,
specie.nome_comune,
specie.nome_scientifico
FROM evento_investimento
JOIN specie ON evento_investimento.specie_id = specie.specie_id
JOIN rilevatore ON evento_investimento.rilevatore_id = rilevatore.rilevatore_id;

CREATE OR REPLACE FUNCTION inserimento_dati_fun_2() RETURNS trigger AS $$
BEGIN
if not exists(select * from rilevatore where rilevatore.nome_cognome=new.nome_cognome) then
INSERT INTO rilevatore (nome_cognome)
VALUES (NEW.nome_cognome);
end if;
if not exists(select * from specie where specie.nome_comune=new.nome_comune) then
INSERT INTO specie (nome_comune, nome_scientifico)
VALUES (NEW.nome_comune, NEW.nome_scientifico);
end if;
INSERT INTO evento_investimento (data, ora, rilevatore_id, specie_id)
VALUES (NEW.data,NEW.ora,
(SELECT rilevatore_id FROM rilevatore WHERE rilevatore.nome_cognome = NEW.nome_cognome),
(SELECT specie_id FROM specie WHERE specie.nome_comune = NEW.nome_comune));
RETURN NEW;
END;
$$ LANGUAGE plpgsql;

create trigger inserimento_dati_fun_trg 
    instead of insert on inserimento_dati_vista for each row EXECUTE procedure inserimento_dati_fun_2();

现在,我想添加一个功能,该功能允许使用inserimento_dati_vista视图更新所有表。

我尝试使用简单的代码仅更新数据列

CREATE OR REPLACE FUNCTION update_dati_fun_2() RETURNS TRIGGER AS $$
BEGIN
IF (TG_OP = 'UPDATE') THEN
IF old.data is distinct from new.data then
UPDATE evento_investimento
SET data = new.data;
END IF;
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;

create trigger update_dati_fun_2_trg
        instead of update on inserimento_dati_vista for each row EXECUTE procedure update_dati_fun_2();

但是,当我执行查询以仅更新一行时,触发器将更新表中的所有行。这里有一些代码可以填充数据。

INSERT INTO inserimento_dati_vista
(data, ora, nome_cognome, nome_comune, nome_scientifico)
VALUES
('2020-01-01', '16:54:00','mario', 'lupo', 'Canis lupus'),
('2020-01-02', '13:54:00','luca', 'lontra', 'Lutra lutra');

UPDATE inserimento_dati_vista
SET data = '2021-01-02' where nome_cognome = 'luca'

1 个答案:

答案 0 :(得分:0)

更新功能为:

CREATE OR REPLACE FUNCTION update_dati_fun_2() RETURNS TRIGGER AS $$
BEGIN
IF (TG_OP = 'UPDATE') THEN
IF old.data is distinct from new.data then
UPDATE evento_investimento e
    SET data = new.data
    FROM rilevatore r
    WHERE nome_cognome = new.nome_cognome AND r.rilevatore_id = e.rilevatore_id;
END IF;
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;