Re: Problem with FOUND

Lists: pgsql-general
From: "A B" <gentosaker(at)gmail(dot)com>
To: pgsql-general(at)postgresql(dot)org
Subject: Problem with FOUND
Date: 2008-06-26 12:43:55
Message-ID: dbbf25900806260543w74650595y66f4e92067ff435a@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

Hi.
I run a function

CREATE OR REPLACE FUNCTION addRating(tbl_ INTEGER,value_ INTEGER)
RETURNS void AS $$
DECLARE
tablename TEXT;
fieldname TEXT;
BEGIN
tablename:='Rating_'||tbl_;
fieldname:='val';
EXECUTE 'UPDATE '||tablename||' SET '||fieldname||'='||value_||'
WHERE '||fieldname||'='||value_ ;
IF NOT FOUND THEN
EXECUTE 'INSERT INTO '||tablename||' ('||fieldname||') VALUES ('||value_||')';
END IF;
END;
$$ LANGUAGE plpgsql;

The UPDATE command works fine (afterwards the table is updated) but it
seems that it do the insert even if it do the update.
I thought this was a correct useage of "FOUND" so that it either do
the update or the insert, not both.
Can anyone help me spot the error?


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: "A B" <gentosaker(at)gmail(dot)com>
Cc: pgsql-general(at)postgresql(dot)org
Subject: Re: Problem with FOUND
Date: 2008-06-26 15:13:24
Message-ID: 16346.1214493204@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

"A B" <gentosaker(at)gmail(dot)com> writes:
> CREATE OR REPLACE FUNCTION addRating(tbl_ INTEGER,value_ INTEGER)
> RETURNS void AS $$
> DECLARE
> tablename TEXT;
> fieldname TEXT;
> BEGIN
> tablename:='Rating_'||tbl_;
> fieldname:='val';
> EXECUTE 'UPDATE '||tablename||' SET '||fieldname||'='||value_||'
> WHERE '||fieldname||'='||value_ ;
> IF NOT FOUND THEN
> EXECUTE 'INSERT INTO '||tablename||' ('||fieldname||') VALUES ('||value_||')';
> END IF;
> END;
> $$ LANGUAGE plpgsql;

> Can anyone help me spot the error?

EXECUTE doesn't set FOUND.

I think you'd be well advised to rethink your table layout so you don't
need so much dynamic SQL. The above is going to suck on both
performance and readability grounds, and it doesn't look like it's
accomplishing anything you couldn't do by combining all the Rating
tables into one table with an extra key column.

regards, tom lane


From: "A B" <gentosaker(at)gmail(dot)com>
To: pgsql-general(at)postgresql(dot)org
Subject: Re: Problem with FOUND
Date: 2008-06-27 08:07:40
Message-ID: dbbf25900806270107r3f3cfd6o3fb798d2854d3e09@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

> I think you'd be well advised to rethink your table layout so you don't
> need so much dynamic SQL. The above is going to suck on both
> performance and readability grounds, and it doesn't look like it's
> accomplishing anything you couldn't do by combining all the Rating
> tables into one table with an extra key column.

Yes, it sucks, but I have to live with it right now (I've also removed
a lot of code from the function to make it more readable for you)
There are a lot of other parameters and execute commands :-(
Since I don't run >=8.2 I cant use FOR-EXECUTE-UPDATE-RETURNING.
So I will have to find another way.

But if UPDATE sets FOUND, what is the reason for EXECUTE not to set
FOUND if the query executed is an UPDATE?
Is it because it is impossible to tell in advance what kind of query
an EXECUTE statement will acctually execute?


From: "Pavel Stehule" <pavel(dot)stehule(at)gmail(dot)com>
To: "A B" <gentosaker(at)gmail(dot)com>
Cc: pgsql-general(at)postgresql(dot)org
Subject: Re: Problem with FOUND
Date: 2008-06-27 08:33:07
Message-ID: 162867790806270133r2e38e2fer1e07d070ac29659b@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

2008/6/27 A B <gentosaker(at)gmail(dot)com>:
>> I think you'd be well advised to rethink your table layout so you don't
>> need so much dynamic SQL. The above is going to suck on both
>> performance and readability grounds, and it doesn't look like it's
>> accomplishing anything you couldn't do by combining all the Rating
>> tables into one table with an extra key column.
>
> Yes, it sucks, but I have to live with it right now (I've also removed
> a lot of code from the function to make it more readable for you)
> There are a lot of other parameters and execute commands :-(
> Since I don't run >=8.2 I cant use FOR-EXECUTE-UPDATE-RETURNING.
> So I will have to find another way.
>
> But if UPDATE sets FOUND, what is the reason for EXECUTE not to set
> FOUND if the query executed is an UPDATE?
> Is it because it is impossible to tell in advance what kind of query
> an EXECUTE statement will acctually execute?

compatibility with Oracle's PL/SQL. Internally isn't reason for it :(
try GET DIAGNOSTICS

postgres=# create table foox(a integer);
CREATE TABLE
postgres=# insert into foox values(10);
INSERT 0 1

postgres=# create function gg(v integer) returns void as $$
declare r integer;
begin execute 'update foox set a = ' || v || '
where a = ' || v;
get diagnostics r = row_count;
raise notice '%', r;
end; $$ language plpgsql;
CREATE FUNCTION
postgres=# select gg(11);
NOTICE: 0
gg
----

(1 row)

postgres=# select gg(10);
NOTICE: 1
gg
----

Regards
Pavel Stehule

>
> --
> Sent via pgsql-general mailing list (pgsql-general(at)postgresql(dot)org)
> To make changes to your subscription:
> http://www.postgresql.org/mailpref/pgsql-general
>


From: "A B" <gentosaker(at)gmail(dot)com>
To: pgsql-general(at)postgresql(dot)org
Subject: Re: Problem with FOUND
Date: 2008-06-27 16:15:57
Message-ID: dbbf25900806270915u659e990n17be0265b4cf164a@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

Thanks for the suggestion on GET DIAGNOSTICS.

But concerning EXECUTE, if I do

BEGIN
EXECUTE QueryA
EXCEPTION WHEN OTHERS THEN
QueryB
END;

will it execute QueryB if QueryA fails?


From: "Pavel Stehule" <pavel(dot)stehule(at)gmail(dot)com>
To: "A B" <gentosaker(at)gmail(dot)com>
Cc: pgsql-general(at)postgresql(dot)org
Subject: Re: Problem with FOUND
Date: 2008-06-27 17:57:00
Message-ID: 162867790806271057hb731c27v87ab42cfa3caaafa@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-general

2008/6/27 A B <gentosaker(at)gmail(dot)com>:
> Thanks for the suggestion on GET DIAGNOSTICS.
>
> But concerning EXECUTE, if I do
>
> BEGIN
> EXECUTE QueryA
> EXCEPTION WHEN OTHERS THEN
> QueryB
> END;
>
>
> will it execute QueryB if QueryA fails?

yes, but it's not preferable way. It creates subtransaction with some
(less) overhead.

Regards
Pavel
>
> --
> Sent via pgsql-general mailing list (pgsql-general(at)postgresql(dot)org)
> To make changes to your subscription:
> http://www.postgresql.org/mailpref/pgsql-general
>