Както може би знаете във всички версии до PostgreSQL 10, не беше възможно да се създаде процедура в PostgreSQL. В PostgreSQL 11 PROCEDURE беше добавена като нов обект на схема, който е подобен обект на FUNCTION, но без връщана стойност.
През годините много хора искаха да имат функционалността и тя най-накрая беше добавена в PostgreSQL 11. Традиционно PostgreSQL предоставя всички средства за писане на функции (които се наричат като съхранени процедури), но във функция не можете да изпълнявате транзакции. Всичко, което наистина можете да използвате, са изключения, които основно са точки за запис. Вътре в тялото на функцията не можете просто да извършите транзакция или да отворите нова. Новата ПРОЦЕДУРА CREATE ще промени всичко това и ще предостави функционалност за изпълнение на транзакции в процедурния код.
Предимства от използването на съхранени процедури
- Контрол на транзакциите, който ни позволява да COMMIT и ROLLBACK вътрешни процедури.
- Много полезна за миграцията на Oracle към PostgreSQL, новата функционалност на процедурата може значително да спести време.
- Както можете да видите, има няколко прилики между CREATE FUNCTION и CREATE PROCEDURE, така че нещата трябва да са наистина лесни за повечето крайни потребители.
Как да използвате съхранена процедура в PostgreSQL
Използвайте CREATE PROCEDURE, за да създадете нова процедура в PostgreSQL 11, тя ще ви позволи да пишете процедура точно като други бази данни. PROCEDURE е почти същата като FUNCTION без върната стойност. PROCEDURE се създава с израза CREATE PROCEDURE в PostgreSQL 11. За разлика от оператора CREATE FUNCTION, няма клауза RETURNS, клауза ROWS и т.н.
Синтаксис
postgres=# \h CREATE PROCEDURE
Command: CREATE PROCEDURE
Description: define a new procedure
Syntax:
CREATE [ OR REPLACE ] PROCEDURE
name ( [ [ argmode ] [ argname ] argtype [ { DEFAULT | = } default_expr ] [, ...] ] )
{ LANGUAGE lang_name
| TRANSFORM { FOR TYPE type_name } [, ... ]
| [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER
| SET configuration_parameter { TO value | = value | FROM CURRENT }
| AS 'definition'
| AS 'obj_file', 'link_symbol'
} ...
Пример
CREATE PROCEDURE procedure1(INOUT p1 TEXT)
AS $$
BEGIN
RAISE NOTICE 'Procedure Parameter: %', p1 ;
END ;
$$
LANGUAGE plpgsql ;
Изпълнете PROCEDURE в PostgreSQL
За да изпълните PROCEDURE в PostgreSQL, използвайте оператора CALL вместо оператора SELECT. Това е една от разликите между ПРОЦЕДУРА и ФУНКЦИЯ.
postgres=# CALL procedure1 (' CREATE PROCEDURE functionality supported in PostgreSQL 11! ');
NOTICE: Procedure Parameter: CREATE PROCEDURE functionality supported in PostgreSQL 11!
p1
--------------------------------------------------------------
CREATE PROCEDURE functionality supported in PostgreSQL 11!
(1 row)
Можете също да посочите име на параметър в оператора CALL. Това е друг начин за изпълнение на ПРОЦЕДУРАТА.
postgres=# CALL procedure1 (p1=>'CREATE PROCEDURE functionality supported in PostgreSQL 11!');
NOTICE: Procedure Parameter: CREATE PROCEDURE functionality supported in PostgreSQL 11!
p1
------------------------------------------------------------
CREATE PROCEDURE functionality supported in PostgreSQL 11!
(1 row)
Показване на списък със създадена ПРОЦЕДУРА
Можете да проверите дефиницията на създадена ПРОЦЕДУРА от командата psql, т.е. '\df'. Командата psql '\df' също се използва за показване на дефиницията на създадена ФУНКЦИЯ.
ПРОЦЕДУРАТА показва колоната Тип като "proc" и ако е FUNCTION, тогава колоната Type се променя на "func".
В списъка с функции по-долу създадохме една ПРОЦЕДУРА, така че колоната Тип се промени на "proc".
postgres=# \df
List of functions
Schema | Name | Result data type | Argument data types | Type
--------+------------+------------------+---------------------+------
public | procedure1 | | INOUT p1 text | proc
(1 row)
Тук можем да създадем една ФУНКЦИЯ, за да проверим колоната Тип.
CREATE FUNCTION function1(INOUT p1 TEXT)
AS $$
BEGIN
RAISE NOTICE 'Function Parameter: %', p1 ;
END ;
$$
LANGUAGE plpgsql ;
Изпълнете FUNCTION с командата SELECT.
postgres=# SELECT function1('CREATE PROCEDURE functionality supported in PostgreSQL 11!');
NOTICE: Function Parameter: CREATE PROCEDURE functionality supported in PostgreSQL 11!
function1
------------------------------------------------------------
CREATE PROCEDURE functionality supported in PostgreSQL 11!
(1 row)
Сега можете да проверите колоната Тип и да видите разликата. За функция FUNCTION1 колоната Type се промени на "func". Можете да видите още една разлика тук, PROCEDURE е почти същата като FUNCTION без връщана стойност.
postgres=# \df
List of functions
Schema | Name | Result data type | Argument data types | Type
--------+------------+------------------+---------------------+------
public | function1 | text | INOUT p1 text | func
public | procedure1 | | INOUT p1 text | proc
(2 rows)
Показване на дефиницията на ПРОЦЕДУРА в PostgreSQL
Използвайте „\sf“, за да покажете дефиницията на създадена ПРОЦЕДУРА.
postgres=# \sf procedure1
CREATE OR REPLACE PROCEDURE public.procedure1(INOUT p1 text)
LANGUAGE plpgsql
AS $procedure$
BEGIN
RAISE NOTICE 'Procedure Parameter: %', p1 ;
END ;
$procedure$
Изтеглете Бялата книга днес Управление и автоматизация на PostgreSQL с ClusterControl Научете какво трябва да знаете, за да внедрите, наблюдавате, управлявате и мащабирате PostgreSQLD Изтеглете Бялата книга Контрол на транзакциите в PROCEDURE
Контрол на транзакциите, което ни позволява да COMMIT и ROLLBACK вътрешни процедури. CREATE FUNCTION не поддържа транзакция вътре във функцията. Това е основната разлика между FUNCTION и PROCEDURE в PostgreSQL.
Нека създадем проста съхранена процедура, която обработва транзакции.
CREATE OR REPLACE PROCEDURE transaction_test()
LANGUAGE plpgsql
AS $$
DECLARE
BEGIN
CREATE TABLE committed_table (id int);
INSERT INTO committed_table VALUES (1);
COMMIT;
CREATE TABLE rollback_table (id int);
INSERT INTO rollback_table VALUES (1);
ROLLBACK;
END $$;
Изпълнете PROCEDURE с оператор CALL.
postgres=# CALL transaction_test();
CALL
Проверете резултата от изпълнението.
postgres=# \d
List of relations
Schema | Name | Type | Owner
--------+-----------------+-------+----------
public | committed_table | table | postgres
(1 row)
postgres=# SELECT * FROM committed_table;
id
----
1
(1 row)
В този блог видяхме контрол на транзакциите за CREATE PROCEDURE, използвайки езика PL/pgSQL, но контролът на транзакциите се предоставя и на други езици като PL/Python, PL/Tcl, PL/Perl.
Синтаксисът за управление на транзакциите на други езици е както следва:
- PL/Python
- plpy.commit()
- plpy.rollback()
- PL/Tcl
- Ангажимент
- връщане назад
- PL/Perl
- spi_commit()
- spi_rollback()
Заключение
CREATE PROCEDURE определено е една от важните и желани функции в PostgreSQL 11. Тази функция е много полезна за миграцията на Oracle към PostgreSQL и много различни случаи на използване и много хора със сигурност я приветстват.