Upgrade to Pro — share decks privately, control downloads, hide ads and more …

PL/pgSQLの基本と使い所

 PL/pgSQLの基本と使い所

OSC京都2025で発表したスライドです。

Avatar for まぐろ

まぐろ

August 03, 2025
Tweet

More Decks by まぐろ

Other Decks in Technology

Transcript

  1. 手続き言語? SQL は一般的なプログラミング言語と異なり宣言型言語に分類される RDB はSQL を採用しているが、実は主要RDBMS には手続き言語が存在する RDBMS 言語 備考

    Oracle PL/SQL Oracle を活用しているところではかなり使われている SQL Server T-SQL PostgreSQL ではPL/pgSQL が標準装備 PL/pgSQL の基本と使い所 3
  2. PL/pgSQL とは SQL を拡張し、手続き処理をできるようにしたのがPL/pgSQL PostgreSQL で手続き処理を作成する際に最もよく使用される言語 PL はProcedural Language (手続き型言語)の略

    Oracle のPL/SQL を参考にしており、書き方がよく似ている PL/SQL からの移行候補にもなりやすい(ただし一筋縄ではいかない) PL/pgSQL の基本と使い所 4
  3. ブロック 必須 説明 宣言部 × 実行部・例外処理部で使用する変数を宣言する 原則、宣言しなければ変数は使用できないが、 変数を使用しない場合は不要 実行部 ◦

    メインの処理を記述する 最悪ここだけあればいい 例外処理部 × 実行部で例外が発生した場合にここの処理に移行する 例外処理を行わない場合は不要 PL/pgSQL の基本と使い所 7
  4. 単純なSQL の実行 CREATE TABLE prefs ( pref_code int not null,

    pref_name text not null, primary key (pref_code) ); INSERT INTO prefs VALUES (11, '埼玉県'); 関数の実行 length(v_pref_name); PL/pgSQL の基本と使い所 9
  5. 変数 PostgreSQL のデータ型は全部対応しています DECLARE v_pref_name text; v_pref_name_length int; BEGIN SELECT

    pref_name INTO v_pref_name FROM prefs WHERE pref_code = 11; v_pref_name_length := length(v_pref_name); END PL/pgSQL の基本と使い所 11
  6. 条件分岐 IF 文の条件判定はWHERE 句の条件判定と同じ書き方ができます IF v_pref_name = '埼玉県' OR v_pref_name

    = '千葉県' THEN RAISE NOTICE '埼玉県、または千葉県です'; ELSE RAISE NOTICE '埼玉県でも千葉県でもありません'; END IF PL/pgSQL の基本と使い所 12
  7. 例外処理 実行中に発生した例外をキャッチすることができます BEGIN PERFORM 10 / 0; EXCEPTION WHEN division_by_zero

    THEN RAISE NOTICE '0除算が実行されました!'; END PL/pgSQL の基本と使い所 14
  8. ストアド・ファンクション DB 内に保存される(stored )関数(function ) 引数と戻り値がある 作る関数はsum() とかmax() とかと同じ「関数」なので、SQL から実行され

    る SQL の関数が使えるところならどこでも使える トランザクションはコミットできない sum() 実行中にトランザクションが終わって始まってたとかいうこと がありえないのと同じ PL/pgSQL の基本と使い所 17
  9. ストアド・ファンクションの作り方 CREATE OR REPLACE FUNCTION 関数名(引数データ型) RETURNS 戻り値データ型 AS $$

    関数本文 ←ここをPL/pgSQLで記述する $$ LANGUAGE plpgsql; PL/pgSQL の基本と使い所 19
  10. ストアド・ファンクションの使い方 SQL の関数が使えるところならどこでも使えます SELECT foo(); INSERT INTO foo_table VALUES (foo());

    長大なSQL の可変部分を引数にして、関数でラップして使い勝手をよくするの もあり PL/pgSQL の基本と使い所 20
  11. ストアド・プロシージャ PostgreSQL 11 から実装された(比較的)新しい機能 10 まではストアド・ファンクションで代用していました DB 内に保存される(stored )手続き(procedure )

    処理をまとめたもので、戻り値がない CALL という専用コマンドで実行する 関数とは異なるため、SQL からは実行できない トランザクションをコミットできる PL/pgSQL の基本と使い所 21
  12. # psqlを実行。 psql <<EOT \set ON_ERROR_STOP on CALL foo(); EOT

    # $?でpsqlコマンドの結果を取得 RESULT=$? PL/pgSQL の基本と使い所 28
  13. プロシージャの例 OUT 引数に結果を格納する CREATE PROCEDURE bar(OUT result int) AS $$

    BEGIN result := 1; END $$ LANGUAGE plpgsql; PL/pgSQL の基本と使い所 31
  14. トリガの作り方 トリガとは別に、トリガ関数を作成する -- 引数なし、戻り値はtrigger CREATE OR REPLACE FUNCTION 関数名() RETURNS

    trigger AS $$ 関数本文 ←ここをPL/pgSQLで記述する $$ LANGUAGE plpgsql; トリガとトリガ関数が分かれているので、異なるテーブルに同じ関数を紐づけ たりもできる PL/pgSQL の基本と使い所 36
  15. トリガの作り方 トリガ関数とテーブルを紐づけてトリガを作成する CREATE TRIGGER トリガ名 BEFORE INSERT ON テーブル名 FOR

    EACH ROW EXECUTE FUNCTION トリガ関数名(); BEFORE 、AFTER やINSERT やUPDATE など、どのタイミングで何のSQL を実行し たタイミングで起動するかも細かく設定できる PL/pgSQL の基本と使い所 37