From: | "Rose, Juergen" <Juergen(dot)Rose(at)sag-el(dot)com> |
---|---|
To: | "Roman Neuhauser" <neuhauser(at)sigpipe(dot)cz> |
Cc: | <pgsql-general(at)postgresql(dot)org> |
Subject: | Re: Insert into ... Select ... From ... too intelligent transaction |
Date: | 2005-07-22 07:10:01 |
Message-ID: | 1EDFE201921585419595B53913CAD6771B36D5@exchange.cegit.de |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-general |
> # Juergen(dot)Rose(at)sag-el(dot)com / 2005-07-21 19:11:04 +0200:
> > I use some updateable views to handle my data (which are amazingly
> > slow), which gives me ultimate flexibility to handle my data.
> >
> > there are some insert rules which use currval() to get the last
> > sequence id for my data which I have to insert.
> >
> > The problem now is, it works fine if I do the statement via normal
> > insert into satatements, even within a transaction block. So far so
> > good. But If I migrate my old data via **Insert into my_new_view
> > Select ... From my_old_table**, Only the last retrieved value of the
> > sequences is used which blows my whole internal logic, because
> > obviously I want to use the current (for that row) and not the last
> > id.
>
> What does the code look like?
>
This is a quite accurate example of what I trying to do, just stripped
down to the bare minimum. Please look at the statements at the end, and
execute them just one after another (test 1-3).
create table olddata(
id int,
lastname varchar(50),
firstname varchar(50)
);
insert into olddata values (1, 'Picard', 'Jean Luc');
insert into olddata values (3, 'Spock', 'Harold');
insert into olddata values (6, 'Zimmerman', 'Doc');
insert into olddata values (9, 'Lefler', 'Robin');
insert into olddata values (10, 'Kirk', 'James T.');
create table neworg(
orgid serial,
legacyid int,
orgname varchar(100)
);
create table newpersons(
persid serial,
orgid int,
lastname varchar(50),
firstname varchar(50)
);
create view v_persons as
select
P.orgid,
O.legacyid,
P.persid,
P.lastname,
P.firstname
from
neworg O,
newpersons P
where
O.orgid = P.orgid;
create or replace rule r_insert_a_organisation as on insert to v_persons
do instead
insert into neworg(
orgid,
legacyid,
orgname)
values (
coalesce(new.orgid, nextval('neworg_orgid_seq')),
new.legacyid,
coalesce(new.lastname, '') || ', ' || coalesce(new.firstname,
'')
);
create or replace rule r_insert_b_persons as on insert to v_persons
do
insert into newpersons(
orgid,
lastname,
firstname)
values (
coalesce(new.orgid, currval('neworg_orgid_seq')),
new.lastname,
new.firstname
);
/* test 1 */
insert into v_persons(legacyid, lastname, firstname) values (11, 'Dax',
'Jadzia');
select * from v_persons;
/* my result:
orgid | legacyid | persid | lastname | firstname
-------+----------+--------+----------+-----------
1 | 11 | 1 | Dax | Jadzia
(1 row)
*/
/* test 2 */
begin;
insert into v_persons(legacyid, lastname, firstname) values (12,
'Bashir', 'Dr.');
insert into v_persons(legacyid, lastname, firstname) values (13, '',
'Odo');
insert into v_persons(legacyid, lastname, firstname) values (14, '',
'Worf');
end;
select * from v_persons;
/* my result:
orgid | legacyid | persid | lastname | firstname
-------+----------+--------+----------+-----------
1 | 11 | 1 | Dax | Jadzia
2 | 12 | 2 | Bashir | Dr.
3 | 13 | 3 | | Odo
4 | 14 | 4 | | Worf
(4 rows)
*/
/* test 3 */
insert into v_persons(legacyid, lastname, firstname) select * from
olddata;
select * from v_persons;
/* my result:
orgid | legacyid | persid | lastname | firstname
-------+----------+--------+-----------+-----------
1 | 11 | 1 | Dax | Jadzia
2 | 12 | 2 | Bashir | Dr.
3 | 13 | 3 | | Odo
4 | 14 | 4 | | Worf
9 | 10 | 5 | Picard | Jean Luc
9 | 10 | 6 | Spock | Harold
9 | 10 | 7 | Zimmerman | Doc
9 | 10 | 8 | Lefler | Robin
9 | 10 | 9 | Kirk | James T.
(9 rows)
*/
And exactly in test 3 you see my problem, it should actually look like
orgid | legacyid | persid | lastname | firstname
-------+----------+--------+-----------+-----------
1 | 11 | 1 | Dax | Jadzia
2 | 12 | 2 | Bashir | Dr.
3 | 13 | 3 | | Odo
4 | 14 | 4 | | Worf
5 | 1 | 5 | Picard | Jean Luc
6 | 3 | 6 | Spock | Harold
7 | 6 | 7 | Zimmerman | Doc
8 | 9 | 8 | Lefler | Robin
9 | 10 | 9 | Kirk | James T.
Why the heck gets the wrong data inserted if it is an int!!!???
I hope somebody will help me out on this, for me this looks very much
like a bug.
Juergen
PS: By the way it is a postgres 7.4.7. on Debian stable
From | Date | Subject | |
---|---|---|---|
Next Message | Richard Huxton | 2005-07-22 07:31:08 | Re: Connection error |
Previous Message | Michael Fuhr | 2005-07-22 05:35:08 | Re: Dumb question about count() |