Thread: SQL stored function inserting and returning data in a row.

SQL stored function inserting and returning data in a row.

From
"Daniel Caune"
Date:
Hi,

Is there any way to define a SQL stored function that inserts a row in a
table and returns the serial generated?

CREATE TABLE matchmaking_session
( session_id bigint NOT NULL DEFAULT
nextval('seq_matchmaking_session_id'), ...
);

CREATE FUNCTION create_matchmaking_sesssion(...) RETURNS bigint
AS $$ INSERT INTO matchmaking_session(...)   VALUES (...)   RETURNING session_id;
$$ LANGUAGE SQL;
2008-01-10 22:08:48 EST ERROR:  return type mismatch in function
declared to return bigint
2008-01-10 22:08:48 EST DETAIL:  Function's final statement must be a
SELECT.
2008-01-10 22:08:48 EST CONTEXT:  SQL function
"create_matchmaking_sesssion"

I can easily convert this code into a PL/pgSQL function, but I'm
thinking that pure SQL is more natural (and faster?) for such a stored
function.

Regards,

--
Daniel


Re: SQL stored function inserting and returning data in a row.

From
Gerardo Herzig
Date:
Daniel Caune wrote:

>Hi,
>
>Is there any way to define a SQL stored function that inserts a row in a
>table and returns the serial generated?
>
>CREATE TABLE matchmaking_session
>(
>  session_id bigint NOT NULL DEFAULT
>nextval('seq_matchmaking_session_id'),
>  ...
>);
>
>CREATE FUNCTION create_matchmaking_sesssion(...)
>  RETURNS bigint
>AS $$
>  INSERT INTO matchmaking_session(...)
>    VALUES (...)
>    RETURNING session_id;
>$$ LANGUAGE SQL;
> 
>2008-01-10 22:08:48 EST ERROR:  return type mismatch in function
>declared to return bigint
>2008-01-10 22:08:48 EST DETAIL:  Function's final statement must be a
>SELECT.
>2008-01-10 22:08:48 EST CONTEXT:  SQL function
>"create_matchmaking_sesssion"
>
>  
>
What about
$$
INSERT INTO .... ;
select currval('seq_matchmaking_session_id');
$$ language sql;

?


Re: SQL stored function inserting and returning data in a row.

From
"Marcin Stępnicki"
Date:
On Jan 11, 2008 4:23 AM, Daniel Caune <daniel.caune@ubisoft.com> wrote:
> Hi,
>
> Is there any way to define a SQL stored function that inserts a row in a
> table and returns the serial generated?

Maybe you just need INSERT ... RETURNING?

http://www.postgresql.org/docs/8.2/interactive/sql-insert.html

" Insert a single row into table distributors, returning the sequence
number generated by the DEFAULT clause:

INSERT INTO distributors (did, dname) VALUES (DEFAULT, 'XYZ Widgets')  RETURNING did;
"


Re: SQL stored function inserting and returning data in a row.

From
"Marcin Stępnicki"
Date:
On Jan 11, 2008 4:23 AM, Daniel Caune <daniel.caune@ubisoft.com> wrote:

Please ignore my post. I havent' read your message carefully enough.


Re: SQL stored function inserting and returning data in a row.

From
"Daniel Caune"
Date:
> What about
> $$
> INSERT INTO .... ;
> select currval('seq_matchmaking_session_id');
> $$ language sql;
>
> ?

Indeed... :-( For some reason, I thought that it was not possible to
have to SQL statement in an SQL stored function.

By the way, is there any performance difference between pure SQL and
PL/pgSQL stored functions?  If I remember correctly there was such a
distinction between pure SQL statement and PL/PLSQL stored procedures
(Oracle), in the sense that PL/PLSQL stored procedures are executed
within the PL/PLSQL engine which sends pure SQL statements to the SQL
engine for execution.  There is a little overhead between PL/PLSQL and
SQL engines.

Regards,

--
Daniel


Re: SQL stored function inserting and returning data in a row.

From
"Pavel Stehule"
Date:
Hello

> By the way, is there any performance difference between pure SQL and
> PL/pgSQL stored functions?  If I remember correctly there was such a
> distinction between pure SQL statement and PL/PLSQL stored procedures
> (Oracle), in the sense that PL/PLSQL stored procedures are executed
> within the PL/PLSQL engine which sends pure SQL statements to the SQL
> engine for execution.  There is a little overhead between PL/PLSQL and
> SQL engines.
>

create or replace function test1(integer)
returns integer as
$$select $1;$$
language sql immutable;

createor replace function test2(integer)
returns integer as
$$begin return  $1; end$$
language plpgsql immutable;

postgres=# select count(*) from (select test1(i) from
generate_series(1,100000) g(i)) f;count
--------100000
(1 row)

Time: 123,532 ms

postgres=# select count(*) from (select test2(i) from
generate_series(1,100000) g(i)) f;count
--------100000
(1 row)

Time: 123,877 ms

but if you forgot immutable
postgres=# create or replace function test3(integer)
returns integer as
$$begin return  $1; end$$
language plpgsql;
CREATE FUNCTION
Time: 430,258 ms
postgres=# select count(*) from (select test3(i) from
generate_series(1,100000) g(i)) f;count
--------100000
(1 row)

Time: 472,150 ms

Regards
Pavel Stehule


Re: SQL stored function inserting and returning data in a row.

From
"Marc Mamin"
Date:
> What about
> $$
> INSERT INTO .... ;
> select currval('seq_matchmaking_session_id');
> $$ language sql;
>
> ?

Hello,

I'm not sure that this would return the correct id in case of concurrent
calls to your function.
I'm using following kind of function to manage reference tables:

HTH,

Marc Mamin


CREATE TABLE xxx
( id serial NOT NULL, mycolumn character varying, CONSTRAINT xxx_pk PRIMARY KEY (id) , CONSTRAINT xxx_uk UNIQUE
(mycolumn)
)



CREATE OR REPLACE FUNCTION get_or_insert_id_xxx( input_value varchar)
RETURNS INT AS $$

DECLARE id_value int;

BEGIN select into id_value id from xxx where mycolumn =  input_value; IF FOUND THEN   return id_value; ELSE   insert
intoxxx ( mycolumn ) values (  input_value );   return id from xxx where mycolumn =  input_value; END IF; 

EXCEPTION WHEN unique_violation THEN   return id from xxx where mycolumn =  input_value;

END;
$$ LANGUAGE plpgsql;