【PostgreSQL】ストアドファンクション・ストアドプロシジャ 違いと用途を徹底比較(初心者)

はじめに

PostgreSQLを使った業務システム開発において、ストアドプロシジャ(PROCEDURE)とストアドファンクション(FUNCTION)は、処理の再利用性や保守性を高める重要な要素です。

本ブログでは、「psql」と「pgAdmin4」を使って、簡単な「本の在庫管理システム」を題材に、両者の違いや使い方を紹介します。

使用環境

  • Windows 11 Pro 24H2
  • PostgreSQL 17.6
  • pgAdmin4 9.6
  • Chrome 134.0.6998.205

ストアドファンクション(Stored Function)とは?

ストアドファンクションは、値を返す処理を定義するSQLの関数です。たとえば「在庫数を取得する」「売上を計算する」といった処理を関数として定義し、SELECT文などから呼び出すことができます。

  • 特徴
    • RETURNS で戻り値を定義
    • SELECT や PERFORM で呼び出し
    • 単一の値や集計結果を返す用途に最適
  • 基本構文
CREATE [OR REPLACE] FUNCTION 関数名(引数 型, ...)
RETURNS 戻り値の型
LANGUAGE plpgsql
AS $$
DECLARE
  -- 変数宣言(任意)
BEGIN
  -- 処理内容
  RETURN 戻り値;
END;
$$;

ストアドプロシジャ(Stored Procedure)とは?

ストアドプロシジャは、複数ステップの処理や副作用を伴う業務ロジックをまとめた手続き型の処理です。たとえば「在庫を更新し、ログを記録する」といった一連の処理を1つのプロシジャにまとめることができます。

  • 特徴
    • 戻り値はなし(ただしOUTパラメータは使える)
    • CALL で呼び出し
    • BEGIN, COMMIT, ROLLBACK によるトランザクション制御が可能
    • 複雑な業務処理に適している
  • 基本構文
CREATE [OR REPLACE] PROCEDURE プロシジャ名(引数 型, ...)
LANGUAGE plpgsql
AS $$
DECLARE
  -- 変数宣言(任意)
BEGIN
  -- 処理内容(複数ステップ可)
  -- トランザクション制御も可能
END;
$$;

ストアドファンクション・ストアドプロシジャの作成と実行

テーブルの作成

先ず 以下のテーブルを作成します。

  • booksテーブル
    在庫数テーブル。在庫数を入力しておき、ストアドファンクションから参照されます。
CREATE TABLE books (
  book_id SERIAL PRIMARY KEY,
  title TEXT NOT NULL,
  stock INT DEFAULT 0
);
  • stock_logs
    在庫数の変化を記録するログテーブルです。ストアドプロシジャによって更新されます。
CREATE TABLE stock_logs (
  log_id SERIAL PRIMARY KEY,
  book_id INT REFERENCES books(book_id),
  change INT,
  log_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

ストアドファンクションの作成

在庫数を取得するストアドファンクションを作成します。

記号:$$は、「ドルクオート(dollar-quoting)」と呼ばれる構文で、関数やプロシジャの本体(つまりPL/pgSQLコード)を囲むための区切り記号です。

-- 関数を作成または置き換える(既存の関数があれば上書き)
CREATE OR REPLACE FUNCTION get_stock(book_title TEXT)
-- 戻り値の型を指定(在庫数:整数)
RETURNS INT AS $$
-- 変数宣言部:在庫数を一時的に保持する変数
DECLARE
  current_stock INT;
BEGIN
  -- booksテーブルから、指定されたタイトルの在庫数を取得し、変数に格納
  SELECT stock INTO current_stock
  FROM books
  WHERE title = book_title;
  -- 取得した在庫数を関数の戻り値として返す
  RETURN current_stock;
END;
-- PL/pgSQL言語で記述された関数であることを指定
$$ LANGUAGE plpgsql;

psqlでの作成

psqlに「CREATE FUNCTION…」文を入力して作成。

pgadmin4 での作成

  • 「関数」右クリック⇀「作成」⇀「関数」
  • 「一般」タブにストアドファンクションの名称を入力
  • 「定義」タブで、「返り値の型」「言語」「引数」を以下の様に設定
  • 「コード」タブには、「DECLARE」文から「END;」までを作成して入力
  • 「オプション」タグの動作属性に、「STABLE」を指定
  • 「パラメータ」タグには下記の値を指定
    • client_min_messages
      • クライアント向けにどのレベルのログ情報出力を指定するかのパラメタ
    • debug1
      • 一般的なデバッグ情報(ユーザー向け)
  • 「保存」ボタンをクリック
    内容は、上記の指定でpgadmin4 が作成した「get_stock」ストアドファンクション
  • 「ストアドファンクション」の詳細については、以下の公式サイトを参照ください。

CREATE FUNCTION(公式ドキュメント)

ストアドプロシジャの作成

在庫数の変化を「stock_logs」テーブルに記録するストアドプロシジャを作成します。

psqlでの作成

psqlに「CREATE PROCEDURE…」文を入力して作成。

pgadmin4 での作成

  • 「プロシージャ」右クリック⇀「作成」⇀「プロシージャ
  • 「一般」タブにストアドプロシジャの名称を入力
  • 「定義」タブで、「言語」「引数」を以下の様に設定
  • 「コード」タブには、「DECLARE」文から「END;」までを作成して入力
  • 「パラメータ」タブは「ストアドファンクション」と同様に設定。
  • 「SQL」タグで内容を確認し、「保存」ボタンをクリック
    • 内容は、上記の指定でpgadmin4 が作成した「update_stock_and_log」ストアドプロシジャ
  • 「ストアドプロシジャ」の詳細については、以下の公式サイトを参照ください。

CREATE PROCEDURE(公式ドキュメント)

ストアドファンクション・ストアドプロシジャの実行

手動実行(psql)して、「ストアドファンクション」及び「ストアドプロシジャ」が正常動作する事を確認します。

【結果】:psql でもadmin4 でも正常動作を確認できました。(当たり前です)

  • ストアドファンクション

psql SELECT 関数名(……)

pgadmin4 SELECT 関数名(……)

  • ストアドプロシジャ

psql CALL プロシジャ名(…..)

pgAdmin4 CALL プロシジャ名(…..)

有効活用できる場面

ストアドファンクション

  • 集計や計算ロジックを共通化したいとき
  • SELECT文の中で使用したいとき
  • トリガーで呼びたいとき
  • トリガーで呼び出したいとき
    • レコードを追加した後での自動処理等

ストアドプロシジャ

  • 複数の更新・挿入処理をまとめたいとき
    • 在庫更新+ログ記録等
  • トランザクション制御を含めたいとき
    • BEGIN ... COMMIT を明示的に扱える
  • 外部から明示的に呼び出す業務処理
    • バッチ処理やAPI連携のエントリポイントとして

まとめ

本ブログでは以下の事項を紹介しました。

  • ストアドファンクションとストアドプロシジャの違い
  • ストアドファンクションとストアドプロシジャの主な用途
  • psql と、pgadmin4(GUI)による作成方法
  • ストアドファンクションとストアドプロシジャの実行方法
  • 有効活用できる場面

ストアドファンクションやストアドプロシジャは、データベースの中で処理を共通化できる事、及びトリガーに応じて起動できる点で有効性が高いと考えられます。但し、ストアドプロシジャは、トリガー関数等を使用する必要が有りますが…。

今回、pgadmin4 でも作成しましたが、初心者にとっては最初の理解に役立つと思うが、一度覚えてしまったら手数の多さが気になって使用しなくなるのではないかと思いました。実際、処理の部分は自分で作成するわけで、GUIのメリットが十分生かされていないと感じた。但し、デバッグできるのは魅力。

タイトルとURLをコピーしました