A PL/pgSQL procedure:
can have zero or more queries with
BEGIN ... ENDclause getting zero or more values with zero or more parameters from the caller. *Be careful,BEGIN ... ENDclause is not transaction.can have
IN,OUT,INOUTandVARIADICparameters. *My answer explains aVARIADICparameter.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.
cannot have RETURN NEXT and RETURN QUERY statement.
can have PERFORM statement.
can have EXECUTE statement. *My post explains how to use
EXECUTEstatement in a function.can have RETURN statement without a value which is
RETURN;.cannot have
RETURNstatement with a value e.g.RETURN 2;otherwise there is error.cannot have SELECT statement without
INTOor INSERT, UPDATE or DELETE statement with RETURNING clause as a non-substatement otherwise there is the error.cannot have
RETURNS <type>clause otherwise there is error.is atomic by default running in a single transaction so if there is error, it is rollbacked automatically. *My answer explains it.
can control transaction with
ROLLBACKandCOMMIT.cannot control transaction with
START TRANSACTIONandBEGINotherwise there is error.is similar to a MySQL procedure.
*The doc explains a PL/pgSQL procedure.
*My post explains a SQL procedure.
*My post explains a PL/pgSQL function.
*My post explains a SQL function.
*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_proc() procedure which adds value to num and returns result to the caller as shown below:
CREATE PROCEDURE my_proc(IN value INT, OUT result INT)
LANGUAGE plpgsql
AS $$
BEGIN
UPDATE test SET num = num + value;
SELECT num INTO result FROM test;
END;
$$;
Or, you can change the position of LANGUAGE plpgsql as shown below:
CREATE PROCEDURE my_proc(IN value INT, OUT result INT)
AS $$
BEGIN
UPDATE test SET num = num + value;
SELECT num INTO result FROM test;
END;
$$
LANGUAGE plpgsql;
*Memos:
An
INparameter can get a value from the caller but cannot return a value to the caller and the parameter with and withoutINis the same somy_proc(IN value INT)andmy_proc(value INT)are the same:An
OUTparameter can return a value to the caller but cannot get a value from the callerAn
OUTparameter cannot haveVOIDtype in a SQL function otherwise there is error while an OUT parameter cannot haveVOIDtype in a PL/pgSQL function:You must set
AS <delimiter>clause andBEGIN ... ENDclause to a PL/pgSQL procedure otherwise there is error.You can also use other delimiter '' instead of $$ to create the body of a PL/pgSQL procedure. *My answer explains it.
You can use
SELECT INTOstatement to put a retrieved value into a variable.If a return value type doesn't match
OUTorINOUTparameters, there is error.You must set
LANGUAGE plpgsqlto create a PL/pgSQL procedure otherwise there is the error.You can set
LANGUAGE plpgsqlin 2 positions as shown above.
Then, you can call my_proc(3, 10) with CALL statement, then 5 is returned and 3 is added to num as shown below. *my_proc() without the 2nd argument or the 2nd argument whose type is not INT get the error:
postgres=# CALL my_proc(3, 10);
result
--------
5
(1 row)
postgres=# SELECT num FROM test;
num
-----
5
(1 row)
And, you can use the INOUT parameter which is the combination of IN and OUT parameters to get a value from the caller and to return a value to the caller as shown below:
CREATE PROCEDURE my_proc(INOUT value INT)
LANGUAGE plpgsql
AS $$
BEGIN
UPDATE test SET num = num + value;
SELECT num INTO value FROM test;
END;
$$;
Then, calling my_proc(3) returns 5 and 3 is added to num as shown below:
postgres=# CALL my_proc(3);
value
-------
5
(1 row)
postgres=# SELECT num FROM test;
num
-----
5
(1 row)
And, you can use RETURN statement without a value which is RETURN; to exit my_proc() as shown below:
CREATE PROCEDURE my_proc(INOUT value INT)
LANGUAGE plpgsql
AS $$
BEGIN
RETURN; -- Here
UPDATE test SET num = num + value;
SELECT num INTO value FROM test;
END;
$$;
Then, calling my_proc(3) returns 3 and nothing is added to num as shown below. *The INOUT parameter value is not changed from 3 to 5:
postgres=# CALL my_proc(3);
value
-------
3
(1 row)
postgres=# SELECT num FROM test;
num
-----
2
(1 row)
And, you can use PERFORM statement as shown below:
CREATE PROCEDURE my_proc(INOUT value INT)
LANGUAGE plpgsql
AS $$
BEGIN
UPDATE test SET num = num + value;
PERFORM num FROM test; -- Here
END;
$$;
Then, calling my_proc(3) returns 3 and 2 is added to num as shown below. *The INOUT parameter value is not changed from 3 to 5:
postgres=# CALL my_proc(3);
value
-------
3
(1 row)
postgres=# SELECT num FROM test;
num
-----
5
(1 row)
And, you can control transaction with ROLLBACK and COMMIT as shown below. *Using START TRANSACTION and BEGIN gets error:
CREATE PROCEDURE my_proc(INOUT value INT)
LANGUAGE plpgsql
AS $$
BEGIN
UPDATE test SET num = num + value;
ROLLBACK;
SELECT num INTO value FROM test;
COMMIT;
END;
$$;
Then, calling my_proc(3) returns 2 and 3 is not added to num as shown below:
postgres=# CALL my_proc(3);
value
-------
2
(1 row)
postgres=# SELECT num FROM test;
num
-----
2
(1 row)
Top comments (0)