Como você deve saber em todas as versões até o PostgreSQL 10, não era possível criar um procedimento no PostgreSQL. No PostgreSQL 11, PROCEDURE foi adicionado como um novo objeto de esquema que é um objeto semelhante a FUNCTION, mas sem valor de retorno.
Ao longo dos anos, muitas pessoas estavam ansiosas para ter a funcionalidade e ela foi finalmente adicionada no PostgreSQL 11. Tradicionalmente, o PostgreSQL fornece todos os meios para escrever funções (que eram chamadas de stored procedures), porém, em uma função você não pode executar transações. Tudo o que você pode realmente usar são exceções, que são basicamente pontos de salvamento. Dentro de um corpo de função você não pode simplesmente confirmar uma transação ou abrir uma nova. O novo CREATE PROCEDURE mudará tudo isso e fornecerá uma funcionalidade para executar transações dentro do código procedural.
Benefícios do uso de procedimentos armazenados
- Controle de transações que nos permite COMMIT e ROLLBACK dentro de procedimentos.
- Muito útil para migração de Oracle para PostgreSQL, a nova funcionalidade de procedimento pode economizar muito tempo.
- Como você pode ver, há algumas semelhanças entre CREATE FUNCTION e CREATE PROCEDURE, então as coisas devem ser muito fáceis para a maioria dos usuários finais.
Como usar o procedimento armazenado no PostgreSQL
Use CREATE PROCEDURE para criar um novo procedimento no PostgreSQL 11, ele permitirá que você escreva o procedimento como em outros bancos de dados. PROCEDURE é quase o mesmo que FUNCTION sem um valor de retorno. PROCEDURE é criado com a instrução CREATE PROCEDURE no PostgreSQL 11. Ao contrário da instrução CREATE FUNCTION, não há cláusula RETURNS, cláusula ROWS etc.
Sintaxe
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'
} ...
Exemplo
CREATE PROCEDURE procedure1(INOUT p1 TEXT)
AS $$
BEGIN
RAISE NOTICE 'Procedure Parameter: %', p1 ;
END ;
$$
LANGUAGE plpgsql ;
Executar PROCEDURE no PostgreSQL
Para executar PROCEDURE no PostgreSQL, use a instrução CALL em vez da instrução SELECT. Esta é uma das diferenças entre PROCEDURE e FUNCTION.
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)
Você também pode especificar o nome do parâmetro na instrução CALL. Esta é outra maneira de executar o PROCEDIMENTO.
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)
Exibir lista de PROCEDIMENTOS criados
Você pode verificar a definição do PROCEDURE criado a partir do comando psql, ou seja, '\df'. O comando psql '\df' também é usado para exibir a definição da FUNÇÃO criada.
O PROCEDURE mostra a coluna Type como "proc" e se for FUNCTION então a coluna Type mudou para "func".
Na lista de funções abaixo, criamos um PROCEDURE para que a coluna Type seja alterada para "proc".
postgres=# \df
List of functions
Schema | Name | Result data type | Argument data types | Type
--------+------------+------------------+---------------------+------
public | procedure1 | | INOUT p1 text | proc
(1 row)
Aqui, podemos criar uma FUNCTION para verificar a coluna Type.
CREATE FUNCTION function1(INOUT p1 TEXT)
AS $$
BEGIN
RAISE NOTICE 'Function Parameter: %', p1 ;
END ;
$$
LANGUAGE plpgsql ;
Execute a FUNCTION usando o comando 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)
Agora você pode verificar a coluna Tipo e ver a diferença. Para a função FUNCTION1, a coluna Type mudou para "func". Você pode ver mais uma diferença aqui, PROCEDURE é quase o mesmo que FUNCTION sem um valor de retorno.
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)
Exibir definição de PROCEDIMENTO no PostgreSQL
Use ‘\sf’ para exibir a definição do PROCEDIMENTO criado.
postgres=# \sf procedure1
CREATE OR REPLACE PROCEDURE public.procedure1(INOUT p1 text)
LANGUAGE plpgsql
AS $procedure$
BEGIN
RAISE NOTICE 'Procedure Parameter: %', p1 ;
END ;
$procedure$
Baixe o whitepaper hoje PostgreSQL Management &Automation with ClusterControlSaiba o que você precisa saber para implantar, monitorar, gerenciar e dimensionar o PostgreSQLBaixe o whitepaper Controle de transações no PROCEDIMENTO
Controle de transações nos permitindo COMMIT e ROLLBACK dentro de procedimentos. CREATE FUNCTION não suporta transações dentro da função. Esta é a principal diferença entre FUNCTION e PROCEDURE no PostgreSQL.
Vamos criar um procedimento armazenado simples que lida com transações.
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 $$;
Execute o PROCEDURE usando a instrução CALL.
postgres=# CALL transaction_test();
CALL
Verifique o resultado da execução.
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)
Neste blog vimos o controle de transações para CREATE PROCEDURE usando a linguagem PL/pgSQL, mas o controle de transações também é fornecido em outras linguagens como PL/Python, PL/Tcl, PL/Perl.
A sintaxe para controle de transações em outras linguagens é a seguinte:
- PL/Python
- plpy.commit()
- plpy.rollback()
- PL/Tcl
- Comprometer
- reversão
- PL/Perl
- spi_commit()
- spi_rollback()
Conclusão
CREATE PROCEDURE é definitivamente um dos recursos importantes e desejáveis no PostgreSQL 11. Esse recurso é muito útil para a migração do Oracle para o PostgreSQL e muitos casos de uso diferentes e muitas pessoas certamente o apreciam.