X-Original-To: pgsql-sql-postgresql.org@localhost.postgresql.org Received: from localhost (unknown [64.117.224.130]) by svr1.postgresql.org (Postfix) with ESMTP id 23381D1B563 for ; Sun, 21 Sep 2003 06:30:58 +0000 (GMT) Received: from svr1.postgresql.org ([64.117.224.193]) by localhost (neptune.hub.org [64.117.224.130]) (amavisd-new, port 10024) with ESMTP id 21260-05 for ; Sun, 21 Sep 2003 03:30:47 -0300 (ADT) Received: from news.hub.org (unknown [64.117.224.194]) by svr1.postgresql.org (Postfix) with ESMTP id E55A6D1B54A for ; Sun, 21 Sep 2003 03:30:45 -0300 (ADT) Received: from news.hub.org (host-64-117-224-194.altec1.com [64.117.224.194] (may be forged)) by news.hub.org (8.12.9/8.12.9) with ESMTP id h8L6UjhK036819 for ; Sun, 21 Sep 2003 06:30:45 GMT (envelope-from news@news.hub.org) Received: (from news@localhost) by news.hub.org (8.12.9/8.12.9/Submit) id h8L69Yep034488 for pgsql-sql@postgresql.org; Sun, 21 Sep 2003 06:09:34 GMT Message-ID: <3F6CDAE6.5010407@houle.org> Date: Sat, 20 Sep 2003 18:55:34 -0400 From: Kevin Houle User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.4) Gecko/20030624 X-Accept-Language: en-us, en MIME-Version: 1.0 X-Newsgroups: comp.databases.postgresql.sql To: Andrew Milne Subject: Re: Unique Constraint Based on Date Range References: <3F69FC7F.1040103@solutioninc.com> In-Reply-To: <3F69FC7F.1040103@solutioninc.com> X-Enigmail-Version: 0.76.2.0 X-Enigmail-Supports: pgp-inline, pgp-mime Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Lines: 50 To: pgsql-sql@postgresql.org X-Virus-Scanned: by amavisd-new at postgresql.org X-Archive-Number: 200309/237 X-Sequence-Number: 15215 Andrew Milne wrote: ... > create table rates ( > effective_date AS timestamp, > expiry_date AS timestamp, > cost AS numeric (12,2), > access_time AS integer (in minutes) > ); > > So for a given cost, there may not be a record where the effective date > of one record overlaps the expiry date of another (and vice versa). > > Example record set (effective date, expiry date, cost, access_time): > > 2003-01-01 | 2003-01-15 | 5.00 | 60 > 2003-01-15 | infinity | 5.00 | 120 > 2003-01-01 | infinity | 1.00 | 10 > > An attempt to insert another 5.00 rate effective now would fail, because > a 5.00 rate exists that doesn't expire (i.e. the expiry date would have > to be updated to the effective date of the new record minus 1 second). > > I can enforce this from the front end, but a db constraint would be great. I don't know that a CHECK constraint would allow you to do this. But, you could create a function to perform the check, and fire a trigger on INSERT or UPDATE to execute the function. For example, something like this might do the trick. CREATE FUNCTION "check_record" () RETURNS TRIGGER AS ' DECLARE result RECORD; BEGIN SELECT INTO result * FROM table_rates WHERE effective_date >= NEW.effective_date AND expiry_date <= NEW.expiry_date AND cost = NEW.cost; IF FOUND THEN RAISE EXCEPTION ''record overlaps with existing record''; END IF; RETURN NEW; END; ' LANGUAGE 'plpgsql'; CREATE TRIGGER "tg_check_record" BEFORE INSERT OR UPDATE ON table_rates FOR EACH ROW EXECUTE PROCEDURE "check_record" (); Kevin