Как реализовать триггер на проверку удаления нескольких обьектов

Имеется вот такая таблица и триггер на проверку удаления к ней.

CREATE TABLE sections_children
(
section_id integer NOT NULL,
child_id integer NOT NULL,
pay_day DATE,
payment int CHECK(payment = 1 OR payment =0) DEFAULT 0
);

CREATE OR REPLACE FUNCTION TriggerTwoF() RETURNS trigger AS
$$
BEGIN
IF(TG_OP = 'DELETE')THEN
 IF OLD.payment = 0 THEN
  RAISE EXCEPTION 'Имеется долг по секции %',OLD.section_id;
 ELSE
  RETURN NEW;
 END IF;
END IF;
END;
$$
LANGUAGE plpgsql;

REATE OR REPLACE TRIGGER TriggerTwo
AFTER DELETE ON sections_children
FOR EACH ROW EXECUTE PROCEDURE TriggerTwoF()

вот я вставляю обьекты.

INSERT INTO sections_children VALUES (1,1,2022-04-01,1);
INSERT INTO sections_children VALUES (1,2,NULL,0);

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

DELETE FROM sections_children WHERE child_id =1 OR 2

Ответы (1 шт):

Автор решения: Roman-Stop RU aggression in UA

Важно сделать две вещи:

  1. триггер нужно сделать BEFORE DELETE, чтоб у него была возможность отменить удаление
  2. В случае, когда не нужно удалять триггер должен возвращать NULL.
CREATE OR REPLACE FUNCTION TriggerTwoF() RETURNS trigger AS
$$
BEGIN
IF(TG_OP = 'DELETE')THEN
 IF OLD.payment = 0 THEN
  RETURN NULL;
 ELSE
  RETURN OLD;
 END IF;
END IF;
END;
$$
LANGUAGE plpgsql;

CREATE OR REPLACE TRIGGER TriggerTwo
BEFORE DELETE ON sections_children
FOR EACH ROW EXECUTE PROCEDURE TriggerTwoF()

Еще замечание, вы похоже используете payment как булевскую переменную. Вместо ручной эмуляции просто используйте тип BOOLEAN, не нужно будет создавать вручную ограничения:

CREATE TABLE sections_children
(
section_id integer NOT NULL,
child_id integer NOT NULL,
pay_day DATE,
payment BOOLEAN DEFAULT false
);


... проверка
IF NOT OLD.payment THEN
→ Ссылка