web-dev-qa-db-ja.com

準備されたステートメントとSQLまたはPL / pgSQL関数の目的の違いは何ですか?

PostgreSQLでは、目的、長所、短所に関して、準備されたステートメントとSQLまたはPL/pgSQL関数の違いは何ですか?いつどれを使用しますか?

この非常に単純な例では、同じように動作しますか?

CREATE TABLE foo (id INT, name VARCHAR(80)); 

CREATE FUNCTION myfunc1(INT, VARCHAR(80)) RETURNS void AS ' 
INSERT INTO foo VALUES ($1, $2);
' LANGUAGE SQL; 

SELECT myfunc1(3, 'ben');

CREATE FUNCTION myfunc2(INT, VARCHAR(80)) RETURNS void AS ' 
BEGIN
INSERT INTO foo VALUES ($1, $2);
END' LANGUAGE plpgsql; 

SELECT myfunc2(3, 'ben');

PREPARE fooplan (INT, VARCHAR(80)) AS
    INSERT INTO foo VALUES($1, $2);
PREPARE

EXECUTE fooplan(3, 'ben');
8
user3284469

3つのすべては、単純なSQLステートメントを実行するという点で「同じように機能します」

INSERT INTO foo VALUES (3, 'ben');

準備済みステートメントは、(名前が示すとおり)single準備済みSQLステートメントにのみ適しています。そして、DMLコマンドのみ。 マニュアル:

SELECTINSERTUPDATEDELETE、またはVALUESステートメント。

関数には、任意の数のステートメントを含めることができます。 DMLandDDL。 SQL関数にはSQLのみ。さらに、PL/pgSQLのいくつかの非SQL手続き要素。

準備されたステートメントは、同じセッション内でのみ表示され、セッションの終了時に表示されますが、関数は永続化され、すべてのユーザーに表示されますが、EXECUTE特権を持つユーザーのみが使用できます。

準備されたステートメントは、最小限のオーバーヘッドで妨げられます。 (大きな違いはありません。)

SQL関数は、クエリプランを(単独で)保存できない3つのうちの1つです。 マニュアルのPL/pgSQL関数でのプランキャッシングの詳細をここで読んでください。

SQL関数は、 inlined になる唯一の関数でもありますより大きなクエリ内で使用されます。 (ただし、INSERTではありません。)

SQL関数とPL/pgSQL関数の違いのかなり包括的なリスト:

Postgres 11以降、SQLプロシージャもあります。

7