[Cialug] Postgres trigger help.

Josh More morej at alliancetechnologies.net
Mon Aug 13 22:57:36 CDT 2007


Here is code that worked in PostgreSQL 7.3.x.  It's old and ugly,
factors which arise due to my being awfully young when I wrote it, and
the fact that it is SQL.  I am just using it to raise exceptions for
error conditions, but you can put anything you like in place of the
RAISE EXCEPTION clause.  I recommend starting with an R.E. though,
because you can debug those awfully easily.

code follows:

CREATE TRIGGER check_event BEFORE INSERT OR UPDATE ON
events_experimental FOR EACH ROW EXECUTE PROCEDURE
check_event_for_datelocation_conflicts();

CREATE FUNCTION check_event_for_datelocation_conflicts () RETURNS opaque
AS '
        DECLARE
                row_data                events_experimental%ROWTYPE;
                room_owner      integer;
        BEGIN
                SELECT INTO room_owner key_user FROM events_location
WHERE id = NEW.key_location;
                -- NEW.key_user == 1 indicates that the user is
webmaster
                IF (NEW.key_user != room_owner) AND (NEW.key_user !=
''1'') THEN
                        RAISE EXCEPTION ''Cannot alter a room that you
do not own'';
                END IF;
                FOR row_data IN SELECT * FROM events_experimental WHERE
key_location = NEW.key_location LOOP
                        IF (row_data.id = NEW.id) and
(row_data.bool_lock) and (NEW.bool_lock) THEN
                                RAISE EXCEPTION ''Cannot modify locked
event % (%)'',row_data.txt_title,row_data.id;
                        END IF;
                        IF (row_data.time_start_time <=
NEW.time_start_time) and (NEW.time_start_time < row_data.time_end_time)
and (row_data.id != NEW.id) and (not row_data.bool_parked) and (not
NEW.bool_parked) THEN
                                RAISE EXCEPTION ''Overlap - Starts
within event % (%)'',row_data.txt_title,row_data.id;
                        END IF;
                        IF (row_data.time_start_time <
NEW.time_end_time) and (NEW.time_end_time <= row_data.time_end_time) and
(row_data.id != NEW.id) and (not row_data.bool_parked) and (not
NEW.bool_parked) THEN
                                RAISE EXCEPTION ''Overlap - Ends within
another event % (%)'',row_data.txt_title,row_data.id;
                        END IF;
                        IF (NEW.time_end_time <= NEW.time_start_time)
THEN
                                RAISE EXCEPTION ''Cannot end before you
start'';
                        END IF;
                END LOOP;
                RETURN NEW;
        END;
' LANGUAGE 'plpgsql';



CREATE TRIGGER check_slot BEFORE INSERT OR UPDATE ON volunteer_slots FOR
EACH ROW EXECUTE PROCEDURE check_slot_for_datelocation_conflicts();

CREATE FUNCTION check_slot_for_datelocation_conflicts () RETURNS opaque
AS '
        DECLARE
                row_data                volunteer_slots%ROWTYPE;
        BEGIN
                FOR row_data IN SELECT * FROM volunteer_slots WHERE
key_job = NEW.key_job LOOP
                        IF (row_data.time_start_time <=
NEW.time_start_time) and (NEW.time_start_time < row_data.time_end_time)
and (row_data.id != NEW.id) THEN
                                RAISE EXCEPTION ''Overlap - Starts
within slot %'',row_data.id;
                        END IF;
                        IF (row_data.time_start_time <
NEW.time_end_time) and (NEW.time_end_time <= row_data.time_end_time) and
(row_data.id != NEW.id) THEN
                                RAISE EXCEPTION ''Overlap - Ends within
another slot %'',row_data.id;
                        END IF;
                        IF (NEW.time_end_time <= NEW.time_start_time)
THEN
                                RAISE EXCEPTION ''Cannot end before you
start'';
                        END IF;
                END LOOP;
                RETURN NEW;
        END;
' LANGUAGE 'plpgsql';






-Josh More, RHCE, CISSP, NCLP, GIAC 
 morej at alliancetechnologies.net 
 515-245-7701

>>> "Tim Wilson" <tim_linux at wilson-home.com> 08/13/07 10:02 PM >>>
I'm using Postgres 7.1.3, and I'm trying to set up a trigger.  I have a
last_updated column on all of my tables, that is of type timestamp.  I
want
to set the field every time the record is updated.  I thought a trigger
would be best for that, but every example I find via Google doesn't
work.
One said to create a function that returned type TRIGGER, another said
type
VOID, neither of which worked.  Every example I find uses one of those
return types.  Anyone have any ideas?

-- 
Tim



More information about the Cialug mailing list