Postgres обновляемый вид - PullRequest
0 голосов
/ 06 марта 2020

в своем приложении я создал представление, чтобы пользователи могли заполнять данные в относительных таблицах. Я сделал представление обновляемым с помощью функции триггера.

BEGIN
INSERT INTO evento_investimento (data, ora, rilevatore_id, strada_id, chilometro_strada,
latitudine, longitudine, barriera_sinistra, barriera_destra, vegetazione_primi_metri, sezione_trasversale,
curvilinearità, uso_suolo_prevalente_50m_destra, uso_suolo_prevalente_50m_sinistra, specie_id, stato_specie_id, sesso_id, classe_id)

VALUES (NEW.data,NEW.ora,
(SELECT rilevatore_id FROM rilevatore WHERE rilevatore.nome_cognome = NEW.nome_cognome),
(SELECT strada_id FROM strada WHERE strada.nome_strada = NEW.nome_strada),
NEW.chilometro_strada, NEW.latitudine, NEW.longitudine, NEW.barriera_sinistra, NEW.barriera_destra, NEW.vegetazione_primi_metri,
NEW.sezione_trasversale, NEW.curvilinearità, NEW.uso_suolo_prevalente_50m_destra, NEW.uso_suolo_prevalente_50m_sinistra,
(SELECT specie_id FROM specie WHERE specie.nome_comune = NEW.nome_comune),
(SELECT stato_specie_id FROM stato_specie WHERE stato_specie.stato = NEW.stato),
(SELECT sesso_id FROM sesso WHERE sesso.sesso_specie = NEW.sesso_specie),
(SELECT classe_id FROM classe_eta WHERE classe_eta.classe_eta = NEW.classe_eta)
);

if not exists(select * from rilevatore where rilevatore.nome_cognome=new.nome_cognome) then
INSERT INTO rilevatore (nome_cognome, telefono, email, ente_appartenenza)
VALUES (NEW.nome_cognome, NEW.telefono, NEW.email, NEW.ente_appartenenza);
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;

if not exists(select * from strada where strada.nome_strada=new.nome_strada) then
INSERT INTO strada (nome_strada)
VALUES (NEW.nome_strada);
end if;

if not exists(select * from sesso where sesso.sesso_specie=new.sesso_specie) then
INSERT INTO sesso (sesso_specie)
VALUES (NEW.sesso_specie);
end if;

if not exists(select * from stato_specie where stato_specie.stato=new.stato) then
INSERT INTO stato_specie (stato)
VALUES (NEW.stato);
end if;

if not exists(select * from classe_eta where classe_eta.classe_eta=classe_eta) then
INSERT INTO classe_eta (classe_eta)
VALUES (NEW.classe_eta);
end if;

RETURN NEW;
END;

Хотя функция отлично работает при заполнении данных, представление не обновляется автоматически, то есть новые данные не отображаются в представлении. , Как я могу решить эту проблему? Заранее спасибо.

[РЕДАКТИРОВАТЬ]

На самом деле, вид работает нормально. Проблема касается таблицы evento_investimento. Если к представлению добавлено новое значение, то есть новое значение spe cie .nome_comune, которого нет в таблице spe cie, функция корректно обновит значение spe cie таблица, но specie_id в таблице evento_investimento не отображается. Как следствие, представление не будет обновляться.

Вот упрощенный пример.

создать таблицу spe cie

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

заполнить таблицу некоторыми значения:

insert into specie
(nome_comune, nome_scientifico)
values
('lupo', 'Canis lupus'),
('lontra', 'Lutra lutra');

создать таблицу rilevatore

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

заполнить таблицу некоторыми значениями:

insert into rilevatore
(nome_cognome)
values
('mario'),
('luca');

создать таблицу evento_investimento

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)
    );

Позвольте заполнить некоторые данные в evento_investimento

insert into evento_investimento
(data, ora, rilevatore_id, specie_id)
values
('2019-12-31', '16:54:00',1,1)

Создать представление для заполнения данных

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
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)
);
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;
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();

Запуск этого кода даст правильные результаты:

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')

Когда я вставляю новый nome_cognome или nome_comune

INSERT INTO inserimento _dati_vista
(data, ora, nome_cognome, nome_comune, nome_scientifico)
VALUES
('2020-01-01', '16:54:00','piero', 'orso', 'Ursus arctos')

таблицы rilevatore и spe cie корректно обновляются, а evento_investimento - нет.

1 Ответ

0 голосов
/ 06 марта 2020

Когда функция работает с заполнением данных в таблицах и проблемы возникают только с представлениями, вам необходимо заново создавать представления после вставки, они не обновляются автоматически.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...