Received: from makus.postgresql.org (makus.postgresql.org [98.129.198.125]) by mail.postgresql.org (Postfix) with ESMTP id 38B8317A3624 for ; Wed, 11 Jul 2012 05:16:25 -0300 (ADT) Received: from mailout02.ims-firmen.de ([213.174.32.97]) by makus.postgresql.org with esmtp (Exim 4.72) (envelope-from ) id 1Sos5v-0008O3-Nn for pgsql-sql@postgresql.org; Wed, 11 Jul 2012 08:16:24 +0000 Received: from mailin03.ims-firmen.de ([192.168.1.143]) by mailout02.ims-firmen.de with esmtp (envelope-from ) id 1Sos5h-0001Ad-kX for pgsql-sql@postgresql.org; Wed, 11 Jul 2012 10:16:09 +0200 Received: from [87.170.179.119] (helo=a-kretschmer.de) by mailin03.ims-firmen.de with esmtpsa (TLSv1:AES256-SHA:256) (envelope-from ) id 1Sos5h-00035X-71 for pgsql-sql@postgresql.org; Wed, 11 Jul 2012 10:16:09 +0200 Received: from kretschmer by a-kretschmer.de with local (Exim 4.69) (envelope-from ) id 1Sos5f-0004p7-Tr for pgsql-sql@postgresql.org; Wed, 11 Jul 2012 10:16:07 +0200 Date: Wed, 11 Jul 2012 10:16:07 +0200 From: Andreas Kretschmer To: pgsql-sql@postgresql.org Subject: Re: Prevent double entries ... no simple unique index Message-ID: <20120711081607.GA17798@tux> References: <4FFD3050.3010509@gmx.net> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <4FFD3050.3010509@gmx.net> X-OS: Debian/GNU Linux - weil ich es mir Wert bin! X-GPG-Fingerprint: EE16 3C01 7B9C 10F7 2C8B 3B86 4DB3 D9EE 7F45 84DA X-Message-Flag: "Windows" is not the answer. "Windows" is the question and the answer is "no"! X-Lugdd: Gerd Kube X-Info: My name is root. Just root. And I am licensed to kill -9 User-Agent: Mutt/1.5.18 (2008-05-17) X-Pg-Spam-Score: -1.9 (-) X-Archive-Number: 201207/6 X-Sequence-Number: 36743 Andreas wrote: > Hi, > > I've got a log-table that records events regarding other objects. > Those events have a state that shows the progress of further work on > this event. > They can be open, accepted or rejected. > > I don't want to be able to insert addition events regarding an object X > as long there is an open or accepted event. > On the other hand as soon as the current event gets rejected a new event > should be possible. > > So there may be several rejected events at any time but no more than 1 > open or accepted entry. > > Can I do this within the DB so I don't have to trust the client app? > > The layout looks like this > Table : objects ( id serial, .... ) > > Table : event_log ( id serial, oject_id integer references objects.id, > state integer, date_created timestamp, ... ) > where state is 0 = open, -1 = reject, 1 = accept test=# create table log (state int not null, check (state in (-1,0,1))); CREATE TABLE Time: 37,527 ms test=*# commit; COMMIT Time: 0,556 ms test=# create unique index on log((case when state in (0,1) then 1 else null end)); CREATE INDEX Time: 18,558 ms test=*# insert into log values (-1); INSERT 0 1 Time: 0,611 ms test=*# insert into log values (-1); INSERT 0 1 Time: 0,274 ms test=*# insert into log values (-1); INSERT 0 1 Time: 0,248 ms test=*# insert into log values (1); INSERT 0 1 Time: 0,294 ms test=*# insert into log values (0); ERROR: duplicate key value violates unique constraint "log_case_idx" DETAIL: Key (( CASE WHEN state = ANY (ARRAY[0, 1]) THEN 1 ELSE NULL::integer END))=(1) already exists. test=!# HTH. Andreas -- Really, I'm not out to destroy Microsoft. That will just be a completely unintentional side effect. (Linus Torvalds) "If I was god, I would recompile penguin with --enable-fly." (unknown) Kaufbach, Saxony, Germany, Europe. N 51.05082°, E 13.56889°