「ストアドプロシージャ」と「ストアドファンクション」の違いは何ですか?


36

したがって、この質問からのコメントは、PostgreSQLの「Stored Procedrues」と「Stored Funtions」にわずかな違いがあると述べています。

コメントはウィキペディアの記事にリンクしていますが、これの一部は当てはまらないようです(たとえば、SELECT声明で使用できるなど)。

構文自体は少し混乱しているようです。

CREATE FUNCTION emp_stamp() RETURNS trigger AS $emp_stamp$
    BEGIN
       [...]
    END;
$emp_stamp$ LANGUAGE plpgsql;

CREATE TRIGGER emp_stamp BEFORE INSERT OR UPDATE ON emp
    FOR EACH ROW EXECUTE PROCEDURE emp_stamp();

を作成しますが、FUNCTIONとして参照しPROCEDUREます。

では、これら2つの違いは何ですか?

回答:


43

公式には、PostgreSQLには「関数」しかありません。トリガー関数は「トリガー手順」と呼ばれることもありますが、その使用法には明確な意味はありません。内部的に、関数はシステムカタログなどでプロシージャと呼ばれることもありますpg_proc。それはPostQUELからの持ち越しです。SQLインジェクションの防止や出力パラメータの使用との関連性など、一部の人々(おそらく異なるデータベースシステムの経験がある)がプロシージャに関連付ける可能性のある機能は、PostgreSQLに存在する機能にも適用されます。

しかし、PostgreSQLコミュニティの人々が「ストアドプロシージャ」または「実際のストアドプロシージャ」について話すとき、それらは多くの場合、本体のトランザクションを開始および停止できる関数のようなオブジェクトの仮想機能を意味します。行う。このコンテキストでの「ストアドプロシージャ」という用語の使用は、他のデータベース製品と類似しているようです。あいまいなアイデアについては、このメーリングリストのスレッドを参照してください。

ただし、実際には、トランザクション制御機能に関するこの関数とプロシージャの区別は普遍的に受け入れられておらず、データベースバイアスのない多くのプログラマーは、プロシージャを戻り値のない関数としてPascalのように解釈します。(SQL標準は、デフォルトではプロシージャが関数とは異なるトランザクション動作を行うという点で、中間的な立場にあるように見えますが、これはオブジェクトごとに調整できます。)聴衆が非常に混在している場合は、想定しすぎず、より明確な用語を使用するか、期待するプロパティを定義する必要があります。


14

DDLに関しては、Postgresにはプロシージャオブジェクトがなく、関数のみがあります。Postgres関数は値またはvoidを返すことができるため、他のRDBMSで関数とプロシージャの両方の役割を引き受けます。の「手順」という言葉create triggerは関数を指します。

Postgresのドキュメントでは、「プロシージャ」は関数と呼ばれるデータベースオブジェクトの同義語でもあります。たとえば、「CREATE FUNCTIONコマンドでトリガープロシージャが作成されます」。

トリガーの「プロシージャ」には特定のルールがあります。それらは、引数を持たず、トリガーの戻りタイプを持つ関数として宣言する必要があります。ここに例。


8

「ストアドプロシージャ」と「ストアドファンクション」という用語はPostgreSQLで同じ意味で使用されており、通常は同じことを意味するものと見なされます。他のデータベースでは、プロシージャと関数を区別する場合があります(VBがサブルーチンと関数を区別する方法と同様)。

PostgreSQLの関数がテーブルに似たものを返す限り、その関数の出力を標準テーブルであるかのように使用できます。CREATE TRIGGER構文は少し混乱ですが、私は、ANSI規格が確定される前に、それが所定の位置にあったかもしれないと思います。私はSQL:2003のコピーしか持っていないので、命名法が奇妙である理由を推測する以上のことはできません。

TL; DRバージョン:PostgreSQLでは、「プロシージャ」は「関数」と同等です。


6

MSSQLでは、ストアドプロシージャは事前にコンパイルされたSQLコマンドのセットです。
ストアドプロシージャ:

 -多くの入力および出力パラメーターを持つことができます
 -データベースのテーブル/構造/データの変更に使用できます
 -通常、insert / update / delete / selectステートメント内では使用されません
ユーザー定義関数にはいくつかの種類があります。作成された関数のタイプに応じて、次の機能があります。
  -複数の入力パラメーターを持つことができますが、単一の値のみを返します(つまり、文字列の連結)
  -セットを入力として受け入れ、単一の値を返すことができます(つまりdbo.FindLargestPig(ListOfPigs))
  -テーブルを返します(つまり、* from dbo.ExplodeString( "this is a list of words"))
  -select / insert / update / deleteステートメントで使用できます
  -データベースのテーブル/構造/データの変更には使用できません


5

簡単な答えは、関数は値を返しますが、プロシージャは返しません。

その区別は、SQL 1992向けに提案されたPersistent Stored Modules(SQL / PSM)に存在しました。SQL/ PSMがこれを標準にしたかどうかはわかりません。


2003年までに
xenoterracide

これは、VBの構文と非常によく似ています。関数は値を返しますが、プロシージャは返しません(関数に戻り値があった場合、コンパイラで
爆発します

@jcolebrand実際には、名前はPascalでより明確です。手順は一方で、結果を返さない関数がありません。歴史的な理由により、VBAはFORTRANの言語を使用します。FORTRANはSUBROUTINEFUNCTIONと呼ばれます(?)。現代のC型言語には関数がありますが、型付き言語には、別の名前のプロシージャであるvoid関数のオプションがあります。一般的な傾向は、すべてに通常の関数を使用し、必要に応じて無視できるものを返すことです。
マンゴー

2

抽象概念レベルから受け入れられた答えを比較すると、機能性と入出力の観点からの違いを理解しています。以下では、spとfを使用して、それぞれストアドプロシージャと関数を表します。

  1. 式での使用:spは式で使用できますが、関数は使用できます。つまり、次のようにafからの戻り値を他のステートメント内で使用できます。

    select * 
    from table 
    where col_a < (select col_A from f())
  2. 値を返す:spは、refcursor戻り型を指定し、カーソルを開いて返すまで、自動的に値を返しません。fは、select句のように 'return'句が埋め込まれた最後のステートメントで結果を返します。

  3. 単一/複数の結果セットを返す:ここで、結果セットは、単一の整数、テキスト配列、2つのテーブルのセットなど、形式が異なる可能性のある結果のリストを参照します。spは、refcursor戻り型を指定し、カーソルを開いて返す限り、複数のセットを返すことができます。ただし、fは1つのタイプのセットのみを返すことができます。

通常、ストアドプロシージャは、削除、更新、削除など、戻り値が不要なデータベースデータまたは構造を変更するために使用されます。または複数の結果セットが必要な状況。一方、関数は、通常、単純なクエリ用に選択されます。

説明の詳細については、このリンクを参照してください:PostgreSQLのストアドプロシージャと関数

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.