В моем тестовом приложении у меня есть база данных со следующей настройкой на примере PostgreSQL9.6
.Postgresql обновляемые представления с ненулевыми ограничениями
CREATE TABLE public.parties
(
id integer NOT NULL DEFAULT nextval('parties_id_seq'::regclass),
party_type_id text NOT NULL,
fullname text NOT NULL DEFAULT ''::text,
created_at timestamp without time zone NOT NULL DEFAULT now(),
CONSTRAINT parties_pkey PRIMARY KEY (id, party_type_id),
(... extra sql not relevant to the question ...)
);
CREATE TABLE public.party_people
(
id integer NOT NULL,
gender text NOT NULL DEFAULT ''::text,
CONSTRAINT party_people_pkey PRIMARY KEY (id),
(... extra sql not relevant to the question ...)
);
CREATE OR REPLACE VIEW public.people AS
SELECT t1.id,
t1.party_type_id,
t1.fullname,
t2.gender,
t1.created_at
FROM parties t1
JOIN party_people t2 ON t1.id = t2.id;
CREATE OR REPLACE FUNCTION public.people_vw_update_func()
RETURNS trigger AS
LANGUAGE plpgsql
$BODY$
BEGIN
IF TG_OP = 'INSERT' THEN
IF NEW.id IS NULL THEN
NEW.id = NEXTVAL('parties_id_seq');
END IF;
INSERT INTO parties
VALUES (NEW.id, NEW.party_type_id, NEW.fullname, NEW.created_at);
INSERT INTO party_people
VALUES (NEW.id, NEW.party_type_id, NEW.gender);
RETURN NEW;
ELSIF
(... extra sql to deal with DELETE and UPDATE cases ...)
END IF;
RETURN NEW;
END;
$BODY$
CREATE TRIGGER people_vw_update_trig
INSTEAD OF INSERT OR UPDATE OR DELETE
ON people
FOR EACH ROW
EXECUTE PROCEDURE people_vw_update_func();
Я пытаюсь создать обновляемый вид в Postgres, где я могу, я могу управлять данными лицами через people
зрения вместо того, чтобы вручную писать запрос, чтобы разделить данные на обеих таблицах.
Проблема Я бегу в том, что я не могу иметь NON NULL
ограничение на таблицах вид отступающих в противном случае запрос типа:
INSERT INTO people (fullname, gender)
VALUES ("James Jones", "male");
потерпит неудачу из-за ограничения на created_at
и потому NEW.create_at
в функция триггера, очевидно, NULL
Так что мой вопрос: кто-нибудь знает, как обрабатывать NON NULL
ограничения внутри обновляемого зрения без г esorting к чему-то вроде:
IF NEW.created_at IS NULL THEN
INSERT INTO parties
VALUES (NEW.id, NEW.party_type_id, NEW.fullname);
ELSE
INSERT INTO parties
VALUES (NEW.id, NEW.party_type_id, NEW.fullname, NEW.created_at);
END IF;
Хотя это решение будет работать для одного столбца, если было гораздо больше, то решение было бы получить действительно грязный очень быстро.
EDIT
В конце концов я реализовал решение, рекомендованное Mad Scientist. Для тех, кто может наткнуться на этот вопрос в будущем мое окончательное решение было:
ALTER TABLE people
ALTER COLUMN created_at SET DEFAULT now()
Таким образом, в триггере зрения все, что я должен был сделать набор значений в соответствующих таблицах как людей мнение будет принимать забота о заполнении переменной NEW
со значениями по умолчанию, где обычно должно быть NULL
.
+1 для рекомендации функции коалесценции. Это в значительной степени точное решение, которое я искал, хотя в конечном итоге я пошел с Mad Scientists, потому что я думаю, что использование значений по умолчанию для представления лучше для моих целей. – Zerodestiny