Chapter 24. PL/pgSQL - SQL手続き言語

Table of Contents
24.1. 概要
24.2. 説明
24.3. トリガプロシージャ
24.4.
24.5. オラクル PL/SQL からの移植

PL/pgSQL は、Postgresデータベースシステム のための読み込み可能な手続き言語です。

このパッケージは Jan Wieck 氏によって書かれたものを元にしています。こ のドキュメントの一部はRoberto Mello 氏によって書かれています。 ().

24.1. 概要

PL/pgSQL の設計目的は、次のような読み込み可能な手続き言語でした。

PL/pgSQL呼び出しハンドラは関数のソーステキストを解析し、初めてその 関数が呼び出された時にバイナリ形式の命令ツリーを内部で作成します。 作成されたバイトコードは呼び出しハンドラ内で関数のオブジェクトIDに よって識別されます。これによって確実に DROP/CREATE といった流れに よる関数の変更を新しくデータベースに接続することなく反映できます。

関数で使用されるすべての式とSQL文に対して、 PL/pgSQLのバイトコードのインタプリタはSPIマネー ジャのSPI_prepare()SPI_saveplan() 関数を使用して遂行可能な実行計 画の準備を作成します。これは、PL/pgSQL 関数内で、初めてその文が処 理された時に行われます。従って、実行計画用に必要となる文を多く含む、 条件付きのコードがある関数は、そのデータベース接続が有効である期間 に実際に使われた部分についての計画のみが作成され、保存されます。

これは、ユーザ定義関数には気をつけなければならないことを示しています。例えば、

CREATE FUNCTION populate() RETURNS INTEGER AS '
DECLARE
     -- 宣言部
BEGIN
    PERFORM my_function();
END;
' LANGUAGE 'plpgsql';
上記のような関数を作成した場合、この関数のバイトコードは my_function()の OID を参照します。このあとで、 例えば、my_function()を削除して作り直した場合、 populate()my_function()を見つけることができません。この 時は、populate()を作り直さなければいけないの です。

PL/pgSQLはこのように実行プランを保存するので、直接 PL/pgSQL 関数内 に現れる問い合わせはあらゆる実行において同じテーブルとフィールドを 参照するものでなければいけません。つまり、問い合わせ中でテーブルや フィールド名を引数として使用することはできません。この制約を回避す る問い合わせ毎に問い合わせプランを作成してしまう無駄を覚悟で PL/pgSQL の EXECUTE 文を使用して動的な問い合わせを作成することです。

入出力変換とユーザ定義型用の計算関数を除き、C言語関数で定義できる 事はすべて PL/pgSQL でも実現できます。複雑な条件のある演算処理関数 の作成や作成した関数を使ったした関数を使った演算子の定義、関数イン デックスに作成した関数を使用することが可能です。

24.1.1. PL/pgSQL を使用することの利点

24.1.1.1. よりよいパフォーマンス

SQLは PostgreSQL(とその他のたいていのリレーショ ナルデータベース)が問い合わせ言語として使用している言語です。可搬 性が有り、習得が容易です。しかし、あらゆるSQL 文は、データベースサーバによって個々に実行されなければいけません。

これはクライアントアプリケーションに対して以下のようなことを要求 しています。まず、データベースサーバに問い合わせを送信します。次 にそれが処理されるのを待ちます。次に、結果を取得します。次に若干 の計算を行います。そしてから、サーバに次の問い合わせを送信します。 クライアントがデータベースサーバマシンからみて異なるマシンの場合、 内部プロセス通信を招き、ネットワーク・オーバーへッドを起こすかも しれません。

PL/pgSQLを使うことで、計算と複数の問い合わせをデータベースサーバ 内部にひとまとめに実行することができます。こ のように、手続き言語の威力と SQL の使いやすさを持ち合わせているに もかかわらず、すべてにおいてクライアント/サーバ通信のオーバーへッ ドがないのでだいぶ時間を節約できます。

24.1.1.2. SQL サポート

PL/pgSQL はSQLの平易性と柔軟性に手続き言語のパ ワーを加えたものです。PL/pgSQL をはすべてのデータ型、カラム、オペ レータ、SQL の関数を使用することができます。

24.1.1.3. 可搬性

PL/pgSQL 関数は PostgreSQL の内部で実行されるので、関数は PostgreSQL が動いていればどんなプラットフォームでも実行できます。 これによって、コードの再利用ができるので、開発コストを削減するこ とができます。

24.1.2. PL/pgSQLでの開発

特にオラクルの PL/SQL のような他のデータベースの手続き言語で開発し たことがあるならば、PL/pgSQL における開発はとても入りやすいでしょ う。PL/pgSQL で開発する2つの良い方法を紹介します。

  • テキストエディタとpsqlを使ってファイルを再 読み込みする方法を使用すること

  • PostgreSQLの GUI ツールである pgaccess を使うこと

PL/pgSQLで開発する一つの良い方法は、単純に関数を作成するのに自分の 好きなテキストエディタを使い、もう一つのコンソールで、 psql(PostgreSQLインタラクティブモニタ)を使用し て関数を読み込ませることです。この方法で行う場合には(そしてあなた が PL/pgSQL 初心者もしくはデバッグ中であれば)関数の作成の前に DROP文でその関数を削除しておくのがよいでしょう。 このようにファイルを再読み込みする場合に、関数を削除して、それから 関数を作り直します。以下が例です。

drop function testfunc(integer);
create function testfunc(integer) return integer as '
    ....
end;
' language 'plpgsql';

初めてファイルを読み込ませる時にはPostgreSQLはこの 関数は存在しないということと、その関数を作成するという警告を発しま す。"dbname" という名前のデータベースに SQLファイル(filename.sql) を読み込ませるには以下のコマンドを使用します。

psql -f filename.sql dbname

Pl/pgSQL における開発のもう一つの良い方法は、 PostgreSQLの GUI ツールである pgaccess を使う方法 です。これを利用すると、シングルクォートをエスケープさせたり、関数 の作り直しやデバッグ関数の作成が容易に行えるという良い点があります。