Postgres 8.4 here. Imagine this code snippet from Postgres doc:
CREATE FUNCTION emp_stamp() RETURNS trigger AS $emp_stamp$
BEGIN
-- Check that empname and salary are given
IF NEW.empname IS NULL THEN
RAISE EXCEPTION 'empname cannot be null';
END IF;
IF NEW.salary IS NULL THEN
RAISE EXCEPTION '% cannot have null salary', NEW.empname;
END IF;
-- Who works for us when she must pay for it?
IF NEW.salary < 0 THEN
RAISE EXCEPTION '% cannot have a negative salary', NEW.empname;
END IF;
-- Remember who changed the payroll when
NEW.last_date := current_timestamp;
NEW.last_user := current_user;
RETURN NEW;
END;
$emp_stamp$ LANGUAGE plpgsql;
If we want to do something like logging in a custom table these exceptions:
-- Check that empname and salary are given
IF NEW.empname IS NULL THEN
INSERT INTO my_log_table ('User didn't supplied empname')
RAISE EXCEPTION 'empname cannot be null';
END IF;
It won't work because anything we put before a RAISE EXCEPTION call is undone by the rollback RAISE EXCEPTION implies, i.e. the my_log_table row we create will be deleted as soon as RAISE EXCEPTION is called.
What's is the best way to accomplish something like this? Maybe catching our custom exception?
Turning off rollback @ TRIGGER is not an option, I need it.
pragma autonomous. Unfortunately, this is still just a proposal, and isn't implemented yet (Postgres 9.3). You could check out this post detailing a common workaround though.