CREATE PROCEDURE — 新しいプロシージャを定義する
CREATE [ OR REPLACE ] PROCEDUREname
( [ [argmode
] [argname
]argtype
[ { DEFAULT | = }default_expr
] [, ...] ] ) { LANGUAGElang_name
| TRANSFORM { FOR TYPEtype_name
} [, ... ] | [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER | SETconfiguration_parameter
{ TOvalue
| =value
| FROM CURRENT } | AS 'definition
' | AS 'obj_file
', 'link_symbol
' |sql_body
} ...
CREATE PROCEDURE
は新たなプロシージャを定義します。
CREATE OR REPLACE PROCEDURE
は新たなプロシージャを作るか、既存の定義を置きかえます。
プロシージャを定義するにはユーザは言語にUSAGE
権限が必要です。
スキーマ名が含まれている場合、プロシージャは指定されたスキーマに作られます。 そうでなければ現在のスキーマに作られます。 同スキーマ内で新たなプロシージャ名と入力引数型が既存のプロシージャや関数と一致してはなりません。 しかしながら、プロシージャや関数が異なる引数型であれば同じ名前を共有できます(これはオーバーロードと呼ばれます)。
既存プロシージャの現在の定義を置き換えるには、CREATE OR REPLACE PROCEDURE
を使用してください。
この方法でプロシージャの名前や引数型を変更することはできません(試みれば、実際は新たな別プロシージャを作ることになるでしょう)。
既存プロシージャの置き換えにCREATE OR REPLACE PROCEDURE
が使われたとき、プロシージャの所有者と権限設定は変更されません。
その他全てのプロシージャ属性は、コマンドで指定された値または暗黙の値に設定されます。
プロシージャを置き換えるには所有者(所有するロールのメンバであることも含みます)でなければなりません。
プロシージャを作ったユーザはプロシージャの所有者になります。
プロシージャを作るには、引数型に対してUSAGE
権限を持っていなければなりません。
プロシージャを書くことに関する更なる情報は38.4を参照してください。
name
作成するプロシージャ名(スキーマ修飾も可)。
argmode
引数モードで、IN
、OUT
、INOUT
、あるいは、VARIADIC
のいずれかです。
省略した場合のデフォルトはIN
です。
argname
引数名。
argtype
プロシージャ引数があるなら、そのデータ型(スキーマ修飾も可)です。 引数型には基本型、複合型、ドメイン型、あるいは、テーブル列の型の参照が使えます。
実装言語によっては、cstring
などの「擬似データ型」を指定することができます。
擬似データ型は実際の引数型が完全には特定されていないか、通常のSQLデータ型の枠外にあることを示しています。
列の型は以下のように参照されます。
.
この機能を使うことは時にプロシージャをテーブル定義の変更から独立させる助けとなります。
table_name
.column_name
%TYPE
default_expr
パラメータが指定されなかった場合のデフォルト値として使用される式です。 この式はパラメータの引数型と変換可能でなければなりません。 デフォルト値を持つパラメータの後ろにあるパラメータはすべて、同様にデフォルト値を持たなければなりません。
lang_name
プロシージャを実装している言語の名前です。
このパラメータには、sql
、c
、internal
、もしくはユーザ定義手続き言語(例:plpgsql
)の名前を指定可能です。
sql_body
が指定されていれば、デフォルトはsql
です。
名前を単一引用符で囲むのは廃止予定で、大文字小文字の一致が必要になります。
TRANSFORM { FOR TYPE type_name
} [, ... ] }
プロシージャ呼び出しにどの変換を適用すべきかのリストです。 変換はSQLの型と言語独自のデータ型の間の変換を行います(CREATE TRANSFORMを参照)。 手続言語の実装では、通常、ビルトインの型についてハードコードされた知識があるので、それらをこのリストに含める必要はありません。 手続言語の実装が型の処理について定めておらず、変換が提供されない場合は、データ型変換のデフォルトの動作によることになりますが、これは実装に依存します。
[EXTERNAL] SECURITY INVOKER
[EXTERNAL] SECURITY DEFINER
SECURITY INVOKER
を指定すると、プロシージャを呼び出したユーザの権限で、そのプロシージャが実行されます。
これがデフォルトです。
SECURITY DEFINER
を指定すると、プロシージャを所有するユーザの権限で、そのプロシージャが実行されます。
EXTERNAL
キーワードは、SQLとの互換性を保つために許されています。
しかし、SQLとは異なり、この機能は外部プロシージャだけではなくすべてのプロシージャに適用されるため、このキーワードは省略可能です。
SECURITY DEFINER
プロシージャではトランザクション制御文(言語によりますが例えばCOMMIT
やROLLBACK
)は実行できません。
configuration_parameter
value
SET
句により、プロシージャが始まった時に指定した設定パラメータを指定した値に設定し、プロシージャの終了時にそれを以前の値に戻すことができます。
SET FROM CURRENT
は、CREATE PROCEDURE
の実行時点でのパラメータ値を、プロシージャに入る時に適用する値として保管します。
プロシージャにSET
句が付いている場合、プロシージャ内部で実行されるSET LOCAL
コマンドの同一変数に対する効果はそのプロシージャに制限されます。
つまり、設定パラメータの前の値はプロシージャが終了する時に元に戻ります。
しかし、通常の(LOCAL
がない)SET
コマンドはSET
句を上書きします。
これは過去に行われたSET LOCAL
コマンドに対してもほぼ同じです。
つまり、このコマンドの効果は、現在のトランザクションがロールバックされない限り、プロシージャが終了した後も永続化されます。
プロシージャにSET
句が付いている場合、そのプロシージャではトランザクション制御文(言語によりますが例えばCOMMIT
とROLLBACK
)を実行できません。
definition
プロシージャを定義する文字列定数です。 このパラメータの意味は言語に依存します。 内部的なプロシージャ名、オブジェクトファイルへのパス、SQLコマンド、あるいは、手続き言語で記述されたテキストを指定できます。
プロシージャを定義する文字列を記述する際に、通常の単一引用符ではなく、ドル引用符(4.1.2.4参照)を使用すると便利なことが多くあります。 ドル引用符を使用しなければ、プロシージャ定義内の単一引用符やバックスラッシュは必ず二重にしてエスケープしなければなりません。
obj_file
, link_symbol
この構文のAS
句は、動的にロードされるC言語プロシージャにおいて、C言語のソースコード中のプロシージャ名がSQLプロシージャの名前と同じでない場合に使われます。
obj_file
という文字列はコンパイルされたCプロシージャを含む共有ライブラリファイルの名前で、LOAD
コマンドの場合と同じように解釈されます。
文字列link_symbol
はそのプロシージャのリンクシンボル、つまり、C言語ソースコード中のプロシージャの名前です。
リンクシンボルが省略された場合、定義されるSQLプロシージャの名前と同じものであるとみなされます。
同じオブジェクトファイルを参照するCREATE PROCEDURE
呼び出しが繰り返される場合、ファイルがセッションにつき一度だけロードされます。
(おそらく開発中に)ファイルのアンロードと再ロードを行うには、新たなセッションを開始してください。
sql_body
LANGUAGE SQL
プロシージャの本体です。
これは以下のようなブロックでなければなりません。
BEGIN ATOMICstatement
;statement
; ...statement
; END
これは文字列定数としてプロシージャ本体を書くのと似ていますが(上記のdefinition
を参照してください)、いくつか違いがあります。
この形式はLANGUAGE SQL
に対してのみ機能し、文字列定数の形式はすべての言語に対して機能します。
この形式はプロシージャ定義時に解析され、文字列定数の形式は実行時に解析されます。
そのため、この形式は多様引数型やプロシージャ定義時に解決できないその他の構文をサポートできません。
この形式はプロシージャとプロシージャ本体の中で使われているオブジェクトの間の依存関係を追跡しますので、DROP ... CASCADE
は正しく動作しますが、一方、文字列定数を使う形式は宙に浮いたプロシージャを放置するかもしれません。
最後に、この形式は標準SQLや他のSQL実装とより互換性があります。
CREATE PROCEDURE insert_data(a integer, b integer) LANGUAGE SQL AS $$ INSERT INTO tbl VALUES (a); INSERT INTO tbl VALUES (b); $$;
または
CREATE PROCEDURE insert_data(a integer, b integer) LANGUAGE SQL BEGIN ATOMIC INSERT INTO tbl VALUES (a); INSERT INTO tbl VALUES (b); END;
and call like this:
CALL insert_data(1, 2);
CREATE PROCEDURE
コマンドは標準SQLで定義されています。
PostgreSQLの実装は互換性のある方法で使うことはできますが、多くの拡張があります。
詳しくはCREATE FUNCTIONも参照してください。