DROP TABLE header; CREATE TABLE header ( distretto CHAR(4) NOT NULL, anno DECIMAL(4) NOT NULL, numero INTEGER NOT NULL, data DATE NOT NULL, azienda CHAR(11) NOT NULL, CONSTRAINT k_header PRIMARY KEY (distretto,anno,numero) ); DROP TABLE detail; CREATE TABLE detail ( distretto CHAR(4) NOT NULL, anno DECIMAL(4) NOT NULL, numero INTEGER NOT NULL, cod_prestazione CHAR(05) NOT NULL, quantita FLOAT(4) NOT NULL, importo FLOAT(8), CONSTRAINT k_detail PRIMARY KEY (distretto,anno,numero,cod_prestazione), CONSTRAINT k_extern FOREIGN KEY(distretto,anno,numero) references HEADER ); drop function f_not_add_detail(); create function f_not_add_detail() returns opaque as ' declare /* to avoid insert detail if header doesn''t exist */ tot int; begin select numero into tot from header where anno = new.anno and numero = new.numero; if not found then raise notice ''Impossible add new detail!''; return NULL; else return new; end if; end; ' language 'plpgsql'; create trigger t_not_add_detail before insert on detail for each row execute procedure f_not_add_detail(); --EXAMPLE: select * from header; select * from detail; INSERT INTO detail VALUES ('E14','1999',2,'IMPOSSIBLE',123,345.5); --impossible INSERT INTO header VALUES ('E14','1999',2,current_date,1235); INSERT INTO detail VALUES ('E14','1999',2,'AB',523,35.5); INSERT INTO header VALUES ('E14','1999',1,current_date,1235); INSERT INTO detail VALUES ('E14','1999',1,'A1',423,45.5); INSERT INTO detail VALUES ('E14','1999',1,'AC',123,345.5); select * from header; select * from detail; drop function f_upd_key_detail(); create function f_upd_key_detail() returns opaque as ' declare /* change in cascade the key of every detail if header key is changed */ tot int; begin update detail set anno = new.anno, numero = new.numero where anno = old.anno and numero = old.numero; return NULL; end; ' language 'plpgsql'; drop trigger t_upd_key_detail on header; create trigger t_upd_key_detail after update on header for each row execute procedure f_upd_key_detail(); --EXAMPLE: select * from header; select * from detail; update header set anno='1997', numero=33 where numero = 1 and anno='1999'; select * from header; select * from detail; drop function f_del_cascade(); create function f_del_cascade() returns opaque as ' declare /* cancel in cascade all details after header is deleted */ begin delete from detail where anno = old.anno and numero = old.numero; return NULL; end; ' language 'plpgsql'; drop trigger t_del_cascade on header; create trigger t_del_cascade after delete on header for each row execute procedure f_del_cascade(); --EXAMPLE: select * from header; select * from detail; delete from header where anno = 1997; select * from header; select * from detail;