PostgreSQL 10までのすべてのバージョンでご存知かもしれませんが、PostgreSQLでプロシージャを作成することはできませんでした。 PostgreSQL 11では、PROCEDUREが新しいスキーマオブジェクトとして追加されました。これはFUNCTIONに似たオブジェクトですが、戻り値はありません。
何年にもわたって多くの人がこの機能を切望し、ついにPostgreSQL 11に追加されました。従来、PostgreSQLは関数(ストアドプロシージャと呼ばれていました)を作成するためのあらゆる手段を提供してきましたが、関数ではトランザクションを実行できません。実際に使用できるのは、基本的にセーブポイントである例外だけです。関数本体の内部では、トランザクションをコミットしたり、新しいトランザクションを開いたりすることはできません。新しいCREATEPROCEDUREはそれをすべて変更し、手続き型コード内でトランザクションを実行する機能を提供します。
ストアドプロシージャを使用する利点
- トランザクション制御により、プロシージャ内でコミットおよびロールバックできます。
- OracleからPostgreSQLへの移行に非常に役立ちます。新しいプロシージャ機能は大幅な時間の節約になります。
- ご覧のとおり、CREATEFUNCTIONとCREATEPROCEDUREにはいくつかの類似点があるため、ほとんどのエンドユーザーにとって非常に簡単なはずです。
PostgreSQLでストアドプロシージャを使用する方法
CREATE PROCEDUREを使用して、PostgreSQL 11で新しいプロシージャを作成します。これにより、他のデータベースと同じようにプロシージャを記述できます。 PROCEDUREは、戻り値のないFUNCTIONとほぼ同じです。 PROCEDUREは、PostgreSQL11のCREATEPROCEDUREステートメントを使用して作成されます。CREATEFUNCTIONステートメントとは異なり、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 ;
PostgreSQLでPROCEDUREを実行する
PostgreSQLでPROCEDUREを実行するには、SELECTステートメントの代わりにCALLステートメントを使用します。これは、PROCEDUREとFUNCTIONの違いの1つです。
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ステートメントでパラメーター名を指定することもできます。これは、PROCEDUREを実行するもう1つの方法です。
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)
作成された手順のリストを表示
作成されたPROCEDUREの定義は、psqlコマンド('\ df')から確認できます。 psqlコマンド'\df'は、作成されたFUNCTIONの定義を表示するためにも使用されます。
PROCEDUREは、Type列を「proc」と表示します。FUNCTIONの場合、Type列は「func」に変更されます。
以下の関数のリストでは、1つのPROCEDUREを作成したため、Type列が「proc」に変更されました。
postgres=# \df
List of functions
Schema | Name | Result data type | Argument data types | Type
--------+------------+------------------+---------------------+------
public | procedure1 | | INOUT p1 text | proc
(1 row)
ここでは、[タイプ]列を確認するための1つの関数を作成できます。
CREATE FUNCTION function1(INOUT p1 TEXT)
AS $$
BEGIN
RAISE NOTICE 'Function Parameter: %', p1 ;
END ;
$$
LANGUAGE plpgsql ;
SELECTコマンドを使用してFUNCTIONを実行します。
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)
これで、[タイプ]列を確認して違いを確認できます。 FUNCTION関数1の場合、Type列が「func」に変更されました。ここでもう1つの違いがわかります。手順は、戻り値のない関数とほぼ同じです。
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$
今日のホワイトペーパーをダウンロードするClusterControlを使用したPostgreSQLの管理と自動化PostgreSQLの導入、監視、管理、スケーリングを行うために知っておくべきことについて学ぶホワイトペーパーをダウンロードする PROCEDUREのトランザクション制御
プロシージャ内でのCOMMITとROLLBACKを可能にするトランザクション制御。 CREATE FUNCTIONは、関数内のトランザクションをサポートしていません。これがPostgreSQLのFUNCTIONとPROCEDUREの主な違いです。
トランザクションを処理する簡単なストアドプロシージャを作成しましょう。
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 $$;
CALLステートメントを使用してPROCEDUREを実行します。
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)
このブログでは、PL /pgSQL言語を使用したCREATEPROCEDUREのトランザクション制御について説明しましたが、トランザクション制御はPL / Python、PL / Tcl、PL/Perlなどの他の言語でも提供されています。
他の言語でのトランザクション制御の構文は次のとおりです。
- PL / Python
- plpy.commit()
- plpy.rollback()
- PL / Tcl
- コミット
- ロールバック
- PL / Perl
- spi_commit()
- spi_rollback()
結論
CREATE PROCEDUREは、間違いなくPostgreSQL 11の重要で望ましい機能の1つです。この機能は、OracleからPostgreSQLへの移行やさまざまなユースケースに非常に役立ち、多くの人がきっと歓迎します。