Каскадное удаление Postgres с триггером - PullRequest
0 голосов
/ 21 сентября 2018

У меня следующая структура базы данных:

table a (
    id     bigint primary key,
    del    timestamp
);
table b (
    id     bigint primary key,
    a_id   bigint references a(id) on delete cascade,
    del    timestamp
);

При удалении записи из таблицы a я хочу установить флаг del в текущий момент времени и установить соответствующий флаг в таблице b (но не удалять записи из базы данных на самом деле).

Для этого я пишу триггер:

create or replace function a_delete_trigger()
    returns trigger as
$$
begin
    update a
    set del = now()
    where id = old.id; -- mark row

    return null; -- return null, so that the record is not removed from database
end;
$$
language plpgsql;
create trigger a_delete
    before delete
    on a
    for each row
execute procedure a_delete_trigger();

И триггер для таблицы b:

create or replace function b_delete_trigger()
    returns trigger as
$$
begin
    update b
    set del = now()
    where id = old.id;

    return null;
end;
$$
language plpgsql;
create trigger b_delete
    before delete
    on b
    for each row
execute procedure b_delete_trigger();

Когда я удаляю запись из таблицы a (delete from a where id = ?), запись помечается как удаленная (флаг del содержит метку времени), но соответствующие записи из таблицы b не помечаются (я предполагаю,, что каскадное удаление не работает, потому что я возвращаю нуль из триггера a_delete_trigger)

Как сделать так, чтобы при удалении записи из таблицы a запись помечалась как удаленная, а соответствующие записи вb будет также помечено как удаленное?

1 Ответ

0 голосов
/ 21 сентября 2018

Добавьте удаление b к a_delete_trigger.

create or replace function a_delete_trigger()
    returns trigger as
$$
begin
    update a
    set del = now()
    where id = old.id; -- mark row

    delete from b where a_id = a.id;

    return null; -- return null, so that the record is not removed from database
end;
$$
language plpgsql;
create trigger a_delete
    before delete
    on a
    for each row
execute procedure a_delete_trigger();
...