Received: from localhost (unknown [200.46.204.182]) by postgresql.org (Postfix) with ESMTP id 6DCFB2E0136 for ; Mon, 10 Dec 2007 07:29:24 -0400 (AST) Received: from postgresql.org ([200.46.204.71]) by localhost (mx1.hub.org [200.46.204.182]) (amavisd-maia, port 10024) with ESMTP id 14587-01 for ; Mon, 10 Dec 2007 07:29:08 -0400 (AST) Received: from moutng.kundenserver.de (moutng.kundenserver.de [212.227.126.171]) by postgresql.org (Postfix) with ESMTP id 3E9B42E00B9 for ; Mon, 10 Dec 2007 07:29:18 -0400 (AST) Received: from webserv.wug.de ([194.25.154.138]) by mrelayeu.kundenserver.de (node=mrelayeu0) with ESMTP (Nemesis) id 0MKwh2-1J1gp03ukV-0007PK; Mon, 10 Dec 2007 12:29:15 +0100 Received: from kretschmer by webserv.wug.de with local (Exim 3.36 #1) id 1J1gp1-0002iW-00 for pgsql-sql@postgresql.org; Mon, 10 Dec 2007 12:29:15 +0100 Date: Mon, 10 Dec 2007 12:29:15 +0100 From: "A. Kretschmer" To: pgsql-sql@postgresql.org Subject: Re: INSERT INTO relational tables Message-ID: <20071210112915.GF917@a-kretschmer.de> References: <20071207172528.820B92C96D4@maia-2.hub.org> <20071209075032.2A1112E3294@postgresql.org> <20071210104204.324340@gmx.net> <20071210110848.GE917@a-kretschmer.de> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20071210110848.GE917@a-kretschmer.de> X-OS: Debian/GNU Linux - weil ich es mir Wert bin! User-Agent: Mutt/1.5.9i X-Provags-ID: V01U2FsdGVkX18EHaXmxnOUKeCq648qB9kwtgb2EYBzdzlZTup 3sxXcopzL/2/nTelBgVRjkhrwbJc8GEiSEWgGLj6FQe67L3LxB +tRuVPR91fsTbR3qJP8izl1BnmHBYdU X-Virus-Scanned: Maia Mailguard 1.0.1 X-Archive-Number: 200712/37 X-Sequence-Number: 29729 am Mon, dem 10.12.2007, um 12:08:48 +0100 mailte A. Kretschmer folgendes: > am Mon, dem 10.12.2007, um 11:42:04 +0100 mailte Stefan Scheidegger folgendes: > > Thanks for your hints so far. > > > > I'm looking for both syntax simplicity and referential integrity. I'm > > using c++ with libpqxx, but I didn't find a good object-relational > > mapper. And I'm too lazy to implement a whole persistency layer as I > > don't have a huge DB with many relations. > > > > I tried Andreas' suggestion with a RULE for INSERT on a VIEW. I > > created the VIEW composing my table with customers and orders: > > > > CREATE VIEW vw_customer_insert AS SELECT * FROM tbl_customer, > > tbl_order WHERE cust_id = ord_customer; > > > > Then I added a rule for the inserting: CREATE RULE rl_customer_insert > > AS ON INSERT TO vw_customer_insert DO INSTEAD ( INSERT INTO > > tbl_customer VALUES (DEFAULT, new.cust_name, new.cust_address); INSERT > > INTO tbl_order VALUES (NEW.ord_pieces, NEW.ord_productname, > > NEW.ord_price, currval('"tbl_cusomer_cust_id_seq"'));); > > > > But this results in the same problem: It works fine if I insert just > > one new customer with one new order. But if I want to insert several > > new entries: > > Insert the new customer only into the table if this customer doesn't > exist there. If the customer exist in the table, obtain the id for this > customer. > > > > simplified: > > - detect, if the customer exists > yes: obtain the id as id > no: insert and use currval() as id > - insert the order with the id > > > I would write a function for this. a little example: test=# create table customer (id serial primary key, name text); NOTICE: CREATE TABLE will create implicit sequence "customer_id_seq" for serial column "customer.id" NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "customer_pkey" for table "customer" CREATE TABLE test=*# create table orders (customer int references customer, val int); CREATE TABLE test=*# create or replace function orders_insert (text, int) returns int as $$declare i int;begin select into i id from customer where name=$1; if i is null then insert into customer (name) values ($1); select into i currval('customer_id_seq'); end if; insert into orders values (i,$2); return i; end; $$language plpgsql; CREATE FUNCTION test=*# select * from customer; id | name ----+------ (0 rows) test=*# select * from orders ; customer | val ----------+----- (0 rows) test=*# select orders_insert('foo',1); orders_insert --------------- 1 (1 row) test=*# select orders_insert('foo',2); orders_insert --------------- 1 (1 row) test=*# select orders_insert('foo',3); orders_insert --------------- 1 (1 row) test=*# select orders_insert('bar',4); orders_insert --------------- 2 (1 row) test=*# select * from customer; id | name ----+------ 1 | foo 2 | bar (2 rows) test=*# select * from orders ; customer | val ----------+----- 1 | 1 1 | 2 1 | 3 2 | 4 (4 rows) HTH, Andreas -- Andreas Kretschmer Kontakt: Heynitz: 035242/47150, D1: 0160/7141639 (mehr: -> Header) GnuPG-ID: 0x3FFF606C, privat 0x7F4584DA http://wwwkeys.de.pgp.net