1

Temat: Problem z regułami przy wstawianiu

Czołem
Zaczynam zabawę z PostgreSQL i trafiłem na problem.
Mam bazę w takim kształcie:

CREATE TABLE parents
(
  parent_id smallint NOT NULL DEFAULT nextval('parents_parent_id_seq'::regclass),
  name character varying(254),
  CONSTRAINT patents_parent_id_key PRIMARY KEY (parent_id)
)

CREATE TABLE children
(
  child_id smallint NOT NULL DEFAULT nextval('children_child_id_seq'::regclass),
  parent_id smallint NOT NULL,
  child_name character varying(254),
  CONSTRAINT children_child_id_key PRIMARY KEY (child_id),
  CONSTRAINT children_parent_id_key FOREIGN KEY (child_id)
      REFERENCES children (child_id) MATCH SIMPLE
      ON UPDATE NO ACTION ON DELETE CASCADE
)

CREATE OR REPLACE VIEW family_view AS 
 SELECT children.child_id,
    children.parent_id,
    children.child_name,
    parents.name AS parent_name
   FROM children,
    parents
  WHERE children.parent_id = parents.parent_id;

CREATE OR REPLACE RULE family_view_i1_parents AS
    ON INSERT TO family_view
   WHERE NOT (EXISTS ( SELECT parents_1.parent_id
           FROM parents parents_1
          WHERE parents_1.name::text = new.parent_name::text)) DO INSTEAD  INSERT INTO parents (name)
  VALUES (new.parent_name);

CREATE OR REPLACE RULE family_view_i2_children AS
    ON INSERT TO family_view DO INSTEAD  INSERT INTO children (child_name, parent_id)
  VALUES (new.child_name, ( SELECT parents.parent_id
           FROM parents
          WHERE parents.name::text = new.parent_name::text));

Założenie było takie, że jeżeli dodaję dane takim zapytaniem:

insert into family_view (child_name, parent_name) values ('dziecko 1', 'rodzic 1')

to jeżeli wpisu o nazwie 'rodzic 1'  nie ma jeszcze w tabeli parents to zostanie dodany.
I to działa.

Natomiast kiedy dodaję dane za pomocą zapytania:

insert into family_view (child_name, parent_name) values ('dziecko 2', 'rodzic 2'),
('dziecko 3', 'rodzic 2'),
('dziecko 4', 'rodzic 2')

występuje błąd:

ERROR: more than one row returned by a subquery used as an expression

Wygląda na to, że przy wywołaniu reguły family_view_i1_parents dla drugiego wiersza, select nie zwraca
żadnego wiersza i zostaje dodany następny, mimo, że w pierwszym wierszu był już dodany.
Następnie w regule family_view_i2_children, select zwraca już dwa wstawione wiersze i stąd ten błąd.
Pytanie dlaczego w family_view_i1_parents select nie znajduje dodanego wcześniej wiersza.
Domyślam się, że to może być związane z transakcjami, ale nie mam wiedzy jak to poprawić.

Z góry dziękuję za pomoc.

2

Odp: Problem z regułami przy wstawianiu

Bardzo ciekawy problem, niby wszystko gra ale postgres się gubi.

Widzę 2 problemy, które mogą to powodować
1 - Nie wiadomo w jakiej kolejności postgres będzie wykonywał RULE na twoim widoku
2 - Klucz obcy na tabeli children powinien być z opcją DEFERRED tak by sprawdzenie kluczy nastąpiło na zakończenie operacji.

Niestety nie udało mi się rozwiązać tego problemu, więc jeśli uda Ci się go rozwiązać to proszę umieść rozwiązanie na forum.