Fredag 30. desember 2011 05.25.22 skrev Jan Bakuwel : > Of course I can start testing existing values in the database before > accepting them in the user interface but that's putting the horse behind > the cart. I much rather use the constraints at the database level to > tell me a particular update can't be done and do that without loosing > everything else I happened to have done in that transaction until that > point.
Here's an example from a plpgsql function I wrote, where a possible violation of unique constraint on (parent_id, source_text) is checked within the transaction: SELECT source_id FROM sources WHERE parent_id = par_id AND source_text = txt INTO x; IF NOT FOUND THEN INSERT INTO sources (parent_id, source_text, sort_order, source_date, part_type) VALUES (par_id, txt, srt, true_date_extract(txt), pt) RETURNING source_id INTO src_id; ELSE RAISE NOTICE 'Source % has the same parent id and text as you tried to enter.', x; RETURN -x; -- abort the transaction and return the offended source id as a negative number. END IF; I don't know if it's considered good form to issue a RETURN in the middle of a function on an error condition, but the main point is that you can take an alternate action when the violation is about to happen. Before I introduced this test, the PHP interface just barfed all over the place with "transaction aborted" messages. Here's another test from the same function, where the alternate action is basically a no-op: -- don't violate unique constraint on (source_fk, event_fk) in the event_citations table. -- if this source-event association already exists, it's rather pointless to repeat it. PERFORM * FROM event_citations WHERE event_fk = event AND source_fk = src_id; IF NOT FOUND THEN INSERT INTO event_citations (event_fk, source_fk) VALUES (event, src_id); ELSE RAISE NOTICE 'citation exists'; END IF; regards, Leif -- Sent via pgsql-sql mailing list (pgsql-sql@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-sql