plpgsql - Using Exception handling to fix foreign key constraint in PL/pgsql (PostgreSQL) -


trying learn exception handling in pgsql (postgresql 9.1). following sp fails with

error: insert or update on table "dx" violates foreign key constraint "fk_icd9" sql state: 23503 detail: key (cicd9, cdesc)=(244.9, testing1) not present in table "icd9". 

fk_icd9 defined table dx as:

constraint fk_icd9 foreign key (cicd9, cdesc)   references icd9 (cicd9, cdesc) match simple   on update cascade on delete restrict deferrable deferred 

my attempt @ sp is:

create or replace function g_test() returns void $$ declare     r view_dx%rowtype; begin   r.cicd9 := '244.9';   r.groupid := 'bbbb      cccc        199971230';     r.tposted := '2013-08-30 17:45:45'::timestamp;   r.cdesc := 'testing1';    loop     begin       update dx set cdesc = r.cdesc       cicd9 = r.cicd9 , groupid = r.groupid , tposted = r.tposted;     exception        when others         insert icd9(cicd9, cdesc) values (r.cicd9, r.cdesc);     end;     if found       return;     end if;    end loop; end; $$ language plpgsql; 

i trying update table, dx, has foreign key constraint in second table, icd9. if update of dx table fails because of constraint, insert new record in parent icd9 table loop first table, dx, update.

what doing wrong? how done?

edit #1: editing code shown below to:

 create or replace function g_savedx3() returns void $$  declare  _cicd9 character varying(8); _groupid character varying(33); _tposted timestamp without time zone; _cdesc character varying(80);    begin _cicd9 := '244.9'; _groupid := 'bbbbb        aaaaa        199998';   _tposted := '2013-08-30 17:45:45'::timestamp; _cdesc := 'testing109';  loop     begin         raise notice 'about update ';          update dx set cdesc = _cdesc                              cicd9 = _cicd9 ,                  groupid = _groupid , tposted = _tposted;          raise notice 'updated in g_savedx3';          if found             return;         end if;           exception              when others                 raise notice 'in exception g_savedx3, insert';                  insert icd9(cicd9,cdesc) values (_cicd9, _cdesc);                  raise notice 'in exception inserted';     end; end loop; end; $$ language plpgsql;  select g_savedx3(); 

yields following messages:

notice: update notice: updated in g_savedx3

error: insert or update on table "dx" violates foreign key constraint "fk_icd9" detail: key (cicd9, cdesc)=(244.9, testing109) not present in table "icd9". ********** error **********

error: insert or update on table "dx" violates foreign key constraint "fk_icd9" sql state: 23503 detail: key (cicd9, cdesc)=(244.9, testing109) not present in table "icd9".

note: found old entry on updates violating foreign constraints tom lane (2004)

yes ... you're expecting ri triggers fire during plpgsql function, in fact fire @ completion of outer statement called plpgsql function.

there's been debate whether desirable behavior, that's how @ moment.

if still case, might explain problem. ideas how fix code? (it should have worked??) thanks.

***as mentioned below, i'm guessing default behavior which, in case, causes exception called after completion of plpgsql function. behavior can changed (postgresql 9.1) with:

set constraints immediate;

which needed make work

if has bearing, here definition of icd9 table:

 create table icd9 (  recid serial not null,  cicd9 character varying(8),  cdesc character varying(80) not null,  "timestamp" timestamp without time zone default now(),  modified timestamp without time zone default now(),  chronic boolean not null default false,  constraint pk_icd9_recid primary key (recid),  constraint constraint_cdesc unique (cicd9, cdesc),  constraint desccheck check (cdesc::text <> ''::text) ) (  oids=false ); 

switch old-fashioned debugging. here code, insert.

create or replace function f () returns void  $$ declare newval integer :=3 ; begin loop begin     raise notice 'about update ';     update b set id2 = newval;     raise notice 'updated ';     if found       return;     end if; exception      when others     raise notice 'in exception , insert';       insert values (newval); raise notice 'in exception inserted'; end; end loop; end; $$ language plpgsql; 

execution:

select f(); notice:  update  notice:  in exception , insert notice:  in exception inserted notice:  update  notice:  updated  

table definitions:

test=# \d+                            table "w2gi.a"  column |  type   | modifiers | storage | stats target | description  --------+---------+-----------+---------+--------------+-------------  id     | integer | not null  | plain   |              |  indexes:     "a_pkey" primary key, btree (id) referenced by:     table "b" constraint "b_id2_fkey" foreign key (id2) references a(id) has oids: no test=# \d+ b                            table "w2gi.b"  column |  type   | modifiers | storage | stats target | description  --------+---------+-----------+---------+--------------+-------------  id1    | integer |           | plain   |              |   id2    | integer |           | plain   |              |  foreign-key constraints:     "b_id2_fkey" foreign key (id2) references a(id) has oids: no 

Comments

Popular posts from this blog

android - MPAndroidChart - How to add Annotations or images to the chart -

javascript - Add class to another page attribute using URL id - Jquery -

firefox - Where is 'webgl.osmesalib' parameter? -