📄 plpgsql.out
字号:
---- PLPGSQL---- Scenario:-- -- A building with a modern TP cable installation where any-- of the wall connectors can be used to plug in phones,-- ethernet interfaces or local office hubs. The backside-- of the wall connectors is wired to one of several patch--- fields in the building.-- -- In the patchfields, there are hubs and all the slots-- representing the wall connectors. In addition there are-- slots that can represent a phone line from the central-- phone system.-- -- Triggers ensure consistency of the patching information.-- -- Functions are used to build up powerful views that let-- you look behind the wall when looking at a patchfield-- or into a room.-- create table Room ( roomno char(8), comment text);create unique index Room_rno on Room using btree (roomno bpchar_ops);create table WSlot ( slotname char(20), roomno char(8), slotlink char(20), backlink char(20));create unique index WSlot_name on WSlot using btree (slotname bpchar_ops);create table PField ( name text, comment text);create unique index PField_name on PField using btree (name text_ops);create table PSlot ( slotname char(20), pfname text, slotlink char(20), backlink char(20));create unique index PSlot_name on PSlot using btree (slotname bpchar_ops);create table PLine ( slotname char(20), phonenumber char(20), comment text, backlink char(20));create unique index PLine_name on PLine using btree (slotname bpchar_ops);create table Hub ( name char(14), comment text, nslots integer);create unique index Hub_name on Hub using btree (name bpchar_ops);create table HSlot ( slotname char(20), hubname char(14), slotno integer, slotlink char(20));create unique index HSlot_name on HSlot using btree (slotname bpchar_ops);create index HSlot_hubname on HSlot using btree (hubname bpchar_ops);create table System ( name text, comment text);create unique index System_name on System using btree (name text_ops);create table IFace ( slotname char(20), sysname text, ifname text, slotlink char(20));create unique index IFace_name on IFace using btree (slotname bpchar_ops);create table PHone ( slotname char(20), comment text, slotlink char(20));create unique index PHone_name on PHone using btree (slotname bpchar_ops);-- ************************************************************-- * -- * Trigger procedures and functions for the patchfield-- * test of PL/pgSQL-- * -- ************************************************************-- ************************************************************-- * AFTER UPDATE on Room-- * - If room no changes let wall slots follow-- ************************************************************create function tg_room_au() returns trigger as 'begin if new.roomno != old.roomno then update WSlot set roomno = new.roomno where roomno = old.roomno; end if; return new;end;' language plpgsql;create trigger tg_room_au after update on Room for each row execute procedure tg_room_au();-- ************************************************************-- * AFTER DELETE on Room-- * - delete wall slots in this room-- ************************************************************create function tg_room_ad() returns trigger as 'begin delete from WSlot where roomno = old.roomno; return old;end;' language plpgsql;create trigger tg_room_ad after delete on Room for each row execute procedure tg_room_ad();-- ************************************************************-- * BEFORE INSERT or UPDATE on WSlot-- * - Check that room exists-- ************************************************************create function tg_wslot_biu() returns trigger as $$begin if count(*) = 0 from Room where roomno = new.roomno then raise exception 'Room % does not exist', new.roomno; end if; return new;end;$$ language plpgsql;create trigger tg_wslot_biu before insert or update on WSlot for each row execute procedure tg_wslot_biu();-- ************************************************************-- * AFTER UPDATE on PField-- * - Let PSlots of this field follow-- ************************************************************create function tg_pfield_au() returns trigger as 'begin if new.name != old.name then update PSlot set pfname = new.name where pfname = old.name; end if; return new;end;' language plpgsql;create trigger tg_pfield_au after update on PField for each row execute procedure tg_pfield_au();-- ************************************************************-- * AFTER DELETE on PField-- * - Remove all slots of this patchfield-- ************************************************************create function tg_pfield_ad() returns trigger as 'begin delete from PSlot where pfname = old.name; return old;end;' language plpgsql;create trigger tg_pfield_ad after delete on PField for each row execute procedure tg_pfield_ad();-- ************************************************************-- * BEFORE INSERT or UPDATE on PSlot-- * - Ensure that our patchfield does exist-- ************************************************************create function tg_pslot_biu() returns trigger as $proc$declare pfrec record; rename new to ps;begin select into pfrec * from PField where name = ps.pfname; if not found then raise exception $$Patchfield "%" does not exist$$, ps.pfname; end if; return ps;end;$proc$ language plpgsql;create trigger tg_pslot_biu before insert or update on PSlot for each row execute procedure tg_pslot_biu();-- ************************************************************-- * AFTER UPDATE on System-- * - If system name changes let interfaces follow-- ************************************************************create function tg_system_au() returns trigger as 'begin if new.name != old.name then update IFace set sysname = new.name where sysname = old.name; end if; return new;end;' language plpgsql;create trigger tg_system_au after update on System for each row execute procedure tg_system_au();-- ************************************************************-- * BEFORE INSERT or UPDATE on IFace-- * - set the slotname to IF.sysname.ifname-- ************************************************************create function tg_iface_biu() returns trigger as $$declare sname text; sysrec record;begin select into sysrec * from system where name = new.sysname; if not found then raise exception $q$system "%" does not exist$q$, new.sysname; end if; sname := 'IF.' || new.sysname; sname := sname || '.'; sname := sname || new.ifname; if length(sname) > 20 then raise exception 'IFace slotname "%" too long (20 char max)', sname; end if; new.slotname := sname; return new;end;$$ language plpgsql;create trigger tg_iface_biu before insert or update on IFace for each row execute procedure tg_iface_biu();-- ************************************************************-- * AFTER INSERT or UPDATE or DELETE on Hub-- * - insert/delete/rename slots as required-- ************************************************************create function tg_hub_a() returns trigger as 'declare hname text; dummy integer;begin if tg_op = ''INSERT'' then dummy := tg_hub_adjustslots(new.name, 0, new.nslots); return new; end if; if tg_op = ''UPDATE'' then if new.name != old.name then update HSlot set hubname = new.name where hubname = old.name; end if; dummy := tg_hub_adjustslots(new.name, old.nslots, new.nslots); return new; end if; if tg_op = ''DELETE'' then dummy := tg_hub_adjustslots(old.name, old.nslots, 0); return old; end if;end;' language plpgsql;create trigger tg_hub_a after insert or update or delete on Hub for each row execute procedure tg_hub_a();-- ************************************************************-- * Support function to add/remove slots of Hub-- ************************************************************create function tg_hub_adjustslots(hname bpchar, oldnslots integer, newnslots integer)returns integer as 'begin if newnslots = oldnslots then return 0; end if; if newnslots < oldnslots then delete from HSlot where hubname = hname and slotno > newnslots; return 0; end if; for i in oldnslots + 1 .. newnslots loop insert into HSlot (slotname, hubname, slotno, slotlink) values (''HS.dummy'', hname, i, ''''); end loop; return 0;end' language plpgsql;-- Test commentsCOMMENT ON FUNCTION tg_hub_adjustslots_wrong(bpchar, integer, integer) IS 'function with args';ERROR: function tg_hub_adjustslots_wrong(character, integer, integer) does not existCOMMENT ON FUNCTION tg_hub_adjustslots(bpchar, integer, integer) IS 'function with args';COMMENT ON FUNCTION tg_hub_adjustslots(bpchar, integer, integer) IS NULL;-- ************************************************************-- * BEFORE INSERT or UPDATE on HSlot-- * - prevent from manual manipulation-- * - set the slotname to HS.hubname.slotno-- ************************************************************create function tg_hslot_biu() returns trigger as 'declare sname text; xname HSlot.slotname%TYPE; hubrec record;begin select into hubrec * from Hub where name = new.hubname; if not found then raise exception ''no manual manipulation of HSlot''; end if; if new.slotno < 1 or new.slotno > hubrec.nslots then raise exception ''no manual manipulation of HSlot''; end if; if tg_op = ''UPDATE'' then if new.hubname != old.hubname then if count(*) > 0 from Hub where name = old.hubname then raise exception ''no manual manipulation of HSlot''; end if; end if; end if; sname := ''HS.'' || trim(new.hubname); sname := sname || ''.''; sname := sname || new.slotno::text; if length(sname) > 20 then raise exception ''HSlot slotname "%" too long (20 char max)'', sname; end if; new.slotname := sname; return new;end;' language plpgsql;create trigger tg_hslot_biu before insert or update on HSlot for each row execute procedure tg_hslot_biu();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -