Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtp (Exim 4.84_2) (envelope-from ) id 1cycQ0-0006NQ-U4 for pgsql-sql@arkaria.postgresql.org; Thu, 13 Apr 2017 10:56:05 +0000 Received: from localhost ([127.0.0.1] helo=postgresql.org) by malur.postgresql.org with smtp (Exim 4.84_2) (envelope-from ) id 1cycQ0-0007Pi-H3 for pgsql-sql@arkaria.postgresql.org; Thu, 13 Apr 2017 10:56:04 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA384:256) (Exim 4.84_2) (envelope-from ) id 1cycOx-0004nB-SO for pgsql-sql@postgresql.org; Thu, 13 Apr 2017 10:54:59 +0000 Received: from mailout02.ims-firmen.de ([213.174.32.97]) by magus.postgresql.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.84_2) (envelope-from ) id 1cycOt-0002Ak-MS for pgsql-sql@postgresql.org; Thu, 13 Apr 2017 10:54:59 +0000 Received: from mailin04.ims-firmen.de ([192.168.1.144]) by mailout02.ims-firmen.de with esmtp (envelope-from ) id 1cycOs-0002v4-jw for pgsql-sql@postgresql.org; Thu, 13 Apr 2017 12:54:54 +0200 Received: from [79.204.168.53] (helo=a-kretschmer.de) by mailin04.ims-firmen.de with esmtpsa (TLSv1:AES256-SHA:256) (envelope-from ) id 1cycOs-0004Su-9g for pgsql-sql@postgresql.org; Thu, 13 Apr 2017 12:54:54 +0200 Received: from kretschmer by a-kretschmer.de with local (Exim 4.69) (envelope-from ) id 1cycOr-0001Jm-HZ for pgsql-sql@postgresql.org; Thu, 13 Apr 2017 12:54:53 +0200 Date: Thu, 13 Apr 2017 12:54:53 +0200 From: Andreas Kretschmer To: pgsql-sql@postgresql.org Subject: Re: Best way to store Master-Detail Data Message-ID: <20170413105453.GA4647@tux> References: MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: 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: -5.4 (-----) List-Archive: List-Help: List-ID: List-Owner: List-Post: List-Subscribe: List-Unsubscribe: X-Mailing-List: pgsql-sql Precedence: bulk Sender: pgsql-sql-owner@postgresql.org Alvin Díaz wrote: > Hi. > > I wan to to know if someone can recommend me the best way to store > header and detail data > in the same function. > > For example: > > I have a table for purchase orders headers and a table for the detail > then i want to record > the header and detail under the same function to make sure that both > header and detail > are committed or not. > > > What i usually do is create a function with such as parameters as fields > in the header table and > after that, i add a same data type parameter for each field in the > detail but as an array. > > In the function, i insert the header data, after that i use a loop on > the first array parameter, > how each array parameter has the same length, i use the ordinal position > to insert the lines. As already suggested, you don't need a function for that, you can use begin and end to put all together in a transaction. Other solution: use writeable Common Table Expression (wCTE) like this example: test=# create table master(id serial primary key, name text); CREATE TABLE test=*# create table detail(master_id int references master, detail_text text); CREATE TABLE test=*# with new_master_id as (insert into master(name) values ('master_new_value') returning id), new_details as (select 'detail1' union all select 'detail2') insert into detail select * from new_master_id cross join (select * from new_details) x; INSERT 0 2 test=*# test=*# test=*# select * from master; id | name ----+------------------ 1 | master_new_value (1 Zeile) test=*# select * from detail ; master_id | detail_text -----------+------------- 1 | detail1 1 | detail2 (2 Zeilen) test=*# with new_master_id as (insert into master(name) values ('master_new_value') returning id), new_details as (select 'detail11' union all select 'detail22') insert into detail select * from new_master_id cross join (select * from new_details) x; INSERT 0 2 test=*# select * from detail ; master_id | detail_text -----------+------------- 1 | detail1 1 | detail2 2 | detail11 2 | detail22 (4 Zeilen) test=*# As you can see, it is just one (in numbers: 1) Insert-Statement ;-) Regards, Andreas Kretschmer -- Andreas Kretschmer http://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services -- Sent via pgsql-sql mailing list (pgsql-sql@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-sql