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.