A PL/pgSQL function:
can have zero or more queries with
BEGIN ... END
statement getting zero or more values with zero or more parameters from the caller. *Be careful,BEGIN ... END
clause is not transaction.can have
IN
,OUT
,INOUT
andVARIADIC
parameters. *My answer explains aVARIADIC
parameter.can have DECLARE clause. *My post explains it.
can have type-only parameters. *My post explains it.
can have the aliases of parameters e.g.
$1
,$2
, etc. *My post explains it.can have SELECT INTO statement.
-
can have RETURN NEXT and RETURN QUERY statement.
can have PERFORM statement.
can have EXECUTE statement. *My post explains how to use
EXECUTE
statement in a function.cannot have SELECT statement without
INTO
or INSERT, UPDATE or DELETE statement with RETURNING clause otherwise there is the error as a non-substatement.can return a value with RETURN statement, an
OUT
orINOUT
parameters to the caller.is atomic by default running in a single transaction so if there is error, it is rollbacked automatically. *My answer explains it.
cannot control transaction with
START TRANSACTION
,BEGIN
,ROLLBACK
,COMMIT
, etc otherwise there is error.is similar to a MySQL function.
*The doc explains a PL/pgSQL function.
*My post explains a SQL function.
*My post explains a PL/pgSQL procedure.
*My post explains a SOL procedure.
*My post explains DO
statement.
*You should use PL/pgSQL language because you can do much more things with it compared with SQL language.
For example, you create test
table as shown below:
CREATE TABLE test (
num INT
);
Then, you insert the row whose num
is 2
into test
table as shown below:
INSERT INTO test (num) VALUES (2);
Now, you can create my_func()
function which adds value
to num
and returns value
to the caller as shown below:
CREATE FUNCTION my_func(value INT) RETURNS INT
AS $$
BEGIN
UPDATE test SET num = num + value;
SELECT num INTO value FROM test;
RETURN value;
END;
$$ LANGUAGE plpgsql;
Or, you can change the position of LANGUAGE plpgsql
as shown below:
CREATE FUNCTION my_func(value INT) RETURNS INT
LANGUAGE plpgsql -- Here
AS $$
BEGIN
UPDATE test SET num = num + value;
SELECT num INTO value FROM test;
RETURN value;
END;
$$;
*Memos:
You must set
RETURNS <type>
clause orOUT
orINOUT
parameters which I explain later otherwise there is error.You must set
AS <delimiter>
clause andBEGIN ... END
clause to a PL/pgSQL function otherwise there is error.RETURNS <type>
clause can haveVOID
type to return nothing.You can also use other delimiter ' instead of $$ to create the body of a PL/pgSQL function. *My answer explains it.
You can use
SELECT INTO
statement to put a retrieved value into a variable.If a return value type doesn't match
RETURNS <type>
clause orOUT
orINOUT
parameters, there is error.If you unset
RETURN
statement whenRETURNS <type>
clause is notVOID
and anOUT
orINOUT
parameter is not used, there is the error.You must set
LANGUAGE plpgsql
to create a PL/pgSQL function otherwise there is the error.You can set
LANGUAGE plpgsql
in 2 positions as shown above.
Then, you can call my_func(3)
with SELECT statement, then 5
is returned and 3
is added to num
as shown below:
postgres=# SELECT my_func(3);
my_func
---------
5
(1 row)
postgres=# SELECT num FROM test;
num
-----
5
(1 row)
And, you can use VOID
type with or without RETURN;
to return nothing as shown below. *Using VOID
type with RETURN <some-value>;
in a PL/pgSQL function gets the error while a SQL function doesn't get the error:
CREATE FUNCTION my_func(value INT) RETURNS VOID
AS $$ -- ↑ Here
BEGIN
UPDATE test SET num = num + value;
SELECT num INTO value FROM test;
RETURN; -- Here
END;
$$ LANGUAGE plpgsql;
Or:
CREATE FUNCTION my_func(value INT) RETURNS VOID
AS $$ -- ↑ Here
BEGIN
UPDATE test SET num = num + value;
SELECT num INTO value FROM test;
-- RETURN; -- Here
END;
$$ LANGUAGE plpgsql;
Then, calling my_func(3)
returns nothing and 3
is added to num
as shown below:
postgres=# SELECT my_func(3);
my_func
---------
(1 row)
postgres=# SELECT num FROM test;
num
-----
5
(1 row)
And, you can use PERFORM
statement as shown below:
CREATE FUNCTION my_func(value INT) RETURNS INT
AS $$
BEGIN
UPDATE test SET num = num + value;
PERFORM num FROM test; -- Here
RETURN 10;
END;
$$ LANGUAGE plpgsql;
Then, calling my_func(3)
returns 10
and 3
is added to num
as shown below:
postgres=# SELECT my_func(3);
my_func
---------
10
(1 row)
postgres=# SELECT num FROM test;
num
-----
5
(1 row)
In addition, you can use IN
, OUT
and INOUT
parameters in a PL/pgSQL function as shown below.
An IN
parameter can get a value from the caller but cannot return a value to the caller. *The parameter with and without IN
is the same so my_func(IN value INT)
and my_func(value INT)
are the same:
CREATE FUNCTION my_func(IN value INT) RETURNS INT
AS $$ -- ↑↑ Here
BEGIN
UPDATE test SET num = num + value;
SELECT num INTO value FROM test;
RETURN value;
END;
$$ LANGUAGE plpgsql;
Then, calling my_func(3)
returns 5
and 3
is added to num
as shown below:
postgres=# SELECT my_func(3);
my_func
---------
5
(1 row)
postgres=# SELECT num FROM test;
num
-----
5
(1 row)
An OUT
parameter can return a value to the caller but cannot get a value from the caller:
CREATE FUNCTION my_func(OUT value INT) RETURNS INT
AS $$ -- ↑ Here
BEGIN
UPDATE test SET num = num + 3;
SELECT num INTO value FROM test;
RETURN;
END;
$$ LANGUAGE plpgsql;
Or:
CREATE FUNCTION my_func(OUT value INT) /* RETURNS INT */
AS $$ -- ↑ Here -- ↑ Unset ↑
BEGIN
UPDATE test SET num = num + 3;
SELECT num INTO value FROM test;
-- RETURN; -- Unset
END;
$$ LANGUAGE plpgsql;
*Memos:
An
OUT
parameter andRETURNS <type>
clause are the same except that anOUT
parameter cannot haveVOID
type in a PL/pgSQL function while anOUT
parameter can in a SQL function.When you set an
OUT
parameter, you can unsetRETURNS <type>
clause andRETURN
statement.You can still set
RETURNS <type>
clause andRETURN
statement with anOUT
parameter but the types of anOUT
parameter andRETURNS <type>
clause must be the same otherwise there is the error andRETURN
statement must beRETURN;
to return nothing otherwise there is the error.Passing a value to an
OUT
parameter gets the error.Setting
VOID
type to anOUT
parameter gets error.
Then, calling my_func()
returns 5
and 3
is added to num
as shown below:
postgres=# SELECT my_func();
my_func
---------
5
(1 row)
postgres=# SELECT num FROM test;
num
-----
5
(1 row)
An INOUT
parameter is the combination of IN
and OUT
parameters to get a value from the caller and to return a value to the caller:
CREATE FUNCTION my_func(INOUT value INT) RETURNS INT
AS $$ -- ↑ Here
BEGIN
UPDATE test SET num = num + value;
SELECT num INTO value FROM test;
RETURN;
END;
$$ LANGUAGE plpgsql;
Or:
CREATE FUNCTION my_func(INOUT value INT) /* RETURNS INT */
AS $$ -- ↑ Here -- ↑ Unset ↑
BEGIN
UPDATE test SET num = num + value;
SELECT num INTO value FROM test;
-- RETURN; -- Unset
END;
$$ LANGUAGE plpgsql;
Then, calling my_func(3)
returns 5
and 3
is added to num
as shown below:
postgres=# SELECT my_func(3);
my_func
---------
5
(1 row)
postgres=# SELECT num FROM test;
num
-----
5
(1 row)
Top comments (0)