web-dev-qa-db-ja.com

PL / SQLのファンクションとプロシージャの違いは何ですか?

PL/SQLの関数とプロシージャの違いは何ですか?

68
Tony

プロシージャには戻り値がありませんが、関数にはあります。

例:

CREATE OR REPLACE PROCEDURE my_proc
   (p_name IN VARCHAR2 := 'John') as begin ... end

CREATE OR REPLACE FUNCTION my_func
   (p_name IN VARCHAR2 := 'John') return varchar2 as begin ... end

関数のパラメーターリストと "as"キーワードの間にreturn句があることに注意してください。これは、関数の本体内の最後のステートメントが次のように読み取られることが期待されることを意味します。

return(my_varchar2_local_variable);

My_varchar2_local_variableは、その関数によって返されるべきvarchar2です。

49
Petros

関数は、SQLステートメントにインライン化できます。

select foo
      ,fn_bar (foo)
  from foobar

ストアドプロシージャでは実行できません。クエリオプティマイザーのアーキテクチャは、このコンテキストの関数で実行できることを制限し、それらが純粋であることを要求します(つまり、同じ入力が常に同じ出力を生成します)。これにより、関数で実行できることは制限されますが、「純粋」に定義されている場合は、クエリでインラインで使用できます。

それ以外の場合、関数(必ずしも決定論的ではない)は変数または結果セットを返すことができます。結果セットを返す関数の場合、クエリ内の他の選択に対してそれを結合できます。ただし、オプティマイザーは返される結果セットの種類を予測できないため、このような非決定的関数を相関サブクエリで使用することはできません(これは停止問題のように計算上扱いにくいです)。

ストアドプロシージャと関数はどちらもデータベースに存在する名前付きブロックであり、必要に応じて実行できます。

主な違いは次のとおりです。

  1. ストアドプロシージャは、オプションで出力パラメーターを使用して値を返すことができますが、値を返さずに方法で記述することもできます。ただし、関数は値を返す必要があります。

  2. ストアドプロシージャはSELECTステートメントでは使用できませんが、関数はSELECTステートメントで使用できます。

実際には、特定の要件グループのストアドプロシージャと、複数のシナリオで共有できる共通の要件の機能を使用します。たとえば、2つの文字列を比較したり、それらをトリミングしたり、最後の部分を取得したりするための関数があれば、それをあらゆるアプリケーションでグローバルに使用できます。

1
Aparna