CREATE PROCEDURE — 新しいプロシージャを定義する
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'
| 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 DEFINERSECURITY INVOKERを指定すると、プロシージャを呼び出したユーザの権限で、そのプロシージャが実行されます。
これがデフォルトです。
SECURITY DEFINERを指定すると、プロシージャを所有するユーザの権限で、そのプロシージャが実行されます。
EXTERNALキーワードは、SQLとの互換性を保つために許されています。
しかし、SQLとは異なり、この機能は外部プロシージャだけではなくすべてのプロシージャに適用されるため、このキーワードは省略可能です。
SECURITY DEFINERプロシージャではトランザクション制御文(言語によりますが例えばCOMMITやROLLBACK)は実行できません。
configuration_parametervalue
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も参照してください。