X-Original-To: pgsql-sql-postgresql.org@localhost.postgresql.org Received: from localhost (av.hub.org [200.46.204.144]) by postgresql.org (Postfix) with ESMTP id DF8B59DC999 for ; Mon, 13 Feb 2006 03:04:04 -0400 (AST) Received: from postgresql.org ([200.46.204.71]) by localhost (av.hub.org [200.46.204.144]) (amavisd-new, port 10024) with ESMTP id 46984-03 for ; Mon, 13 Feb 2006 03:04:04 -0400 (AST) X-Greylist: from auto-whitelisted by SQLgrey- Received: from floppy.pyrenet.fr (news.pyrenet.fr [194.116.145.2]) by postgresql.org (Postfix) with ESMTP id 07A349DC98F for ; Mon, 13 Feb 2006 03:04:01 -0400 (AST) Received: by floppy.pyrenet.fr (Postfix, from userid 106) id CE7693093D; Mon, 13 Feb 2006 08:04:01 +0100 (MET) From: "rlee0001" X-Newsgroups: pgsql.sql Subject: Re: Trigger/Sequence headache Date: 12 Feb 2006 23:03:52 -0800 Organization: http://groups.google.com Lines: 40 Message-ID: <1139814232.642459.326740@g43g2000cwa.googlegroups.com> References: <20060212150559.S97294@megazone.bigpanda.com> <000f01c6302b$9be85760$2101a8c0@cfgod> Mime-Version: 1.0 Content-Type: text/plain; charset="iso-8859-1" X-Complaints-To: groups-abuse@google.com In-Reply-To: <000f01c6302b$9be85760$2101a8c0@cfgod> User-Agent: G2/0.2 X-HTTP-UserAgent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.8.0.1) Gecko/20060111 Firefox/1.5.0.1,gzip(gfe),gzip(gfe) Complaints-To: groups-abuse@google.com Injection-Info: g43g2000cwa.googlegroups.com; posting-host=70.128.225.153; posting-account=W1HrJhMAAABKoEyjN0n9NdMFZKbfU7Ty3txgz4qxiVmANE6LfCsvZA To: pgsql-sql@postgresql.org X-Virus-Scanned: by amavisd-new at hub.org X-Spam-Status: No, score=0.7 required=5 tests=[AWL=0.151, FORGED_HOTMAIL_RCVD2=0.549] X-Spam-Score: 0.7 X-Spam-Level: X-Archive-Number: 200602/225 X-Sequence-Number: 24235 Stephen, You don't need to use a seperate batch to clean up the table. As Stephan pointed out, you can call nextval after you determine that the new row isn't a duplicate. In case you misunderstood what Stephan had suggested let me try to explain what is happening. When PostgreSQL receives an INSERT request it aggregates field values for the new row from several sources. 1) The statement itself (INSERT INTO ... VALUES ...) 2) The fields' DEFAULT values (provided by the CREATE TABLE statement) 3) Any CONSTRANTs are taken into consideration 4) BEFORE triggers are called in alphabetical order 5) The new row is inserted 6) AFTER triggers are called in alphabetical order The sequence is being incrimented when NEXTVAL is evaluated. NEXTVAL can be evaluated in steps 1, 2 or 4 depending on how your application is written. Since you want to be able to cancel the operation in step 4 without NEXTVAL having been evaluated, this is where you should call NEXTVAL (instead of in steps 1 or 2). So in your trigger you want to do something like this: -- Check for duplicates here...RETURN NULL; NEW.ID = NEXTVAL('SEQ_MYTABLE_ID'); RETURN NEW; Also, are you sure you want to return NULL rather than raise an exception? Either way will work depending on what the desired behavour is. The thing is that silently dropping rows might be the source of a debugging nightmare later on where-as raising an exception is a bit easier to detect. Just me $0.02. To raise an exception see RAISE EXCEPTION in the postgresql manual. Its really easy but will cancel the current transaction so it may not be desirable for your uses. -Robert