web-dev-qa-db-ja.com

ストアドプロシージャ/ユーザー定義関数を使用する場合

SP/UDFの使用について混乱しています。通常、データベース外のプログラムでコードを書くことも可能です。それらをいつ使用するかを決定するための一般的なアドバイスはありますか?

3
DANG Fan

更新

Postgres11は、最終的にSQLプロシージャ(「ストアドプロシージャ」)を導入し、また、トランザクションの開始と終了:

ただし、トランザクションブロックで許可されていないコマンドは(まだ)含めることができません。重要な例CREATE DATABASEまたはCREATE INDEX CONCURRENTLYまたはVACUUM

また、INOUTパラメータを使用して作成されたプロシージャは、単一の結果行のみを返すことができます。

真のストアドプロシージャはこれらの制限を課しません。今後のリリースでさらに改善される可能性があります。


元の答え

Postgres 11以前は、厳密に言えば「ストアドプロシージャ」はありませんでした。 関数だけで、ほとんど同じではありませんが、まったく同じではありません。最も重要なのは、関数が常にトランザクション内で実行されることです。これは、ロック管理、トラップエラー、またはトランザクションコンテキストで実行できないコマンド(上記を参照)にとって重要です。関連:

SQLでデータを処理することには、すべての生データをアプリケーションに取得して計算を行うよりも大きな利点があります。

(data-modifying)CTE で「チェーンされた」コマンドを使用する場合でも、単一のステートメントでは実行できない大きな操作に同じ原理を適用できます。

ユースケースにもよりますが、関数canはパフォーマンスが優れており、特に複数のアプリが同じデータベースにアクセスする場合に便利です。 サーバー側の言語を選択する 、最も一般的にはSQLまたはPL/pgSQLを実行する必要があります。

競合する同時トランザクションが存在する場合(マルチユーザー環境)簡単に。同じ関数には、アトミックである必要があるだけを入れてください。可能であれば、多くのロックを伴う長いトランザクションを避けてください。ロックはトランザクションの終了時にのみ解放されます。長いトランザクションは同時アクセスを停止させる可能性があり、デッドロックにつながる可能性があります(これらは、Postgresによって自動的に検出および解決され、競合するトランザクションのエラーが発生し、ロールバックされます)...

これらのアンチパターンを回避する場合、サーバー側の機能は優れたツールになる可能性があります。いくつかの目的のためにmustとにかくトリガー関数のような関数を使用します。

10