28
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

トリガ・トリガプロシージャの使い方(PostgreSQL)

Last updated at Posted at 2019-10-23

#トリガ・トリガプロシージャとは
 トリガとは、あるテーブルに対してINSERT文やUPDATE文、DELET文を実行したときに、同時にプロシージャ(関数のようなもの)を呼び出す機能です。トリガプロシージャとはこのときに呼び出されるプロシージャのことです。ちなみに英語でtriggerは、「引き起こす」を意味します。
 今回の記事では、トリガプロシージャを作成し、トリガを利用する簡単な例を紹介したいと思います。

#トリガ・トリガプロシージャの作成と実行
##作成するもの
 割り算したいものをテーブルに挿入したときに、同時に答えも挿入するトリガ、トリガプロシージャを作成します。
 operandテーブルは割り算する数を入れるテーブルです。answerテーブルはoperandテーブルの割り算の結果を入れるテーブルです。operand1列をoperand2列で割ったときの商をanswerテーブルのquotient列へ、余りをanswerテーブルのremainderへ入れます。
 今回作成するトリガは、operandテーブルに数値をINSERTしたときに、トリガプロシージャを呼び出してanswerテーブルにも同時に計算結果を入れるものです。

operand1 ÷ operand2 = quotient(商)・・・remainder(余り)

operandテーブル

id | operand1 | operand2
----+----------+----------
1 | 1 | 5
2 | 2 | 5
3 | 3 | 5
4 | 4 | 5
5 | 5 | 5

answerテーブル

id | quotient | remainder
----+----------+-----------
1 | 0 | 1
2 | 0 | 2
3 | 0 | 3
4 | 0 | 4
5 | 1 | 0

##(1)トリガプロシージャの作成
 トリガプロシージャを作成します。作り方は、ストアドプロシージャやストアドファンクションと大体は同じですが、以下の点で異なります。

・引数は持たない
・戻り値は必ずtrigger型の値(NEWなどをRETURNする)
・NEWを使用することで、トリガを発動するINSERT文の結果を入れることができる((3)のINSERTするときの値を使うことができる)。

詳しいことは以下のPostgreSQLのマニュアルを参考にしてください。

CREATE FUNCTION div_proc() RETURNS trigger AS $div_proc$  --引数なし、戻り値trigger型の関数として宣言 
BEGIN
  --トリガを呼び出すINSERT文の結果を使ってidと商、余りをanswerテーブルに挿入する
  INSERT INTO answer VALUES (NEW.id, div(NEW.operand1, NEW.operand2), mod(NEW.operand1, NEW.operand2));  
  RETURN NEW;  --trigger型変数のNEWをRETURNする。
END;
$div_proc$
LANGUAGE plpgsql;   --言語を指定

##(2)トリガの作成
 上で作ったトリガプロシージャを使って、トリガを作成します。以下は、operandテーブルにINSERT文を実行した後に、div_proc()トリガプロシージャを呼び出す、div_trgトリガを作成しています。FOR EACH ROWは1行operandテーブルにINSERTするたびにトリガを呼び出すことを意味しています。
 トリガの書き方の詳細は以下のPostgreSQLのマニュアルを参考にしてください。

書式:CREATE TRIGGER トリガ名 AFTER INSERT ON テーブル名 FOR EACH ROW
    EXECUTE FUNCTION トリガプロシージャ名;

CREATE TRIGGER div_trg AFTER INSERT ON operand FOR EACH ROW
EXECUTE FUNCTION div_proc();

##(3)実行
 作成したトリガを使用します。

postgres=# INSERT INTO operand VALUES(6,6,5);
INSERT 0 1

 実行後のテーブルは以下のようになります。operandテーブルにINSERTしただけですが、answerテーブルにも計算結果がINSERTされていることが確認できます。

operandテーブル

id | operand1 | operand2
----+----------+----------
1 | 1 | 5
2 | 2 | 5
3 | 3 | 5
4 | 4 | 5
5 | 5 | 5
6 | 6 | 5

answerテーブル

id | quotient | remainder
----+----------+-----------
1 | 0 | 1
2 | 0 | 2
3 | 0 | 3
4 | 0 | 4
5 | 1 | 0
6 | 1 | 1

#(参考)作成したトリガを確認する方法
 テーブルに作成したトリガを確認することができます。Triggersのところにトリガの内容が書かれています。

書き方:\d テーブル名

postgres=# \d operand
               Table "public.operand"
  Column  |  Type   | Collation | Nullable | Default
----------+---------+-----------+----------+---------
 id       | integer |           | not null |
 operand1 | integer |           |          |
 operand2 | integer |           |          |
Indexes:
    "operand_pkey" PRIMARY KEY, btree (id)
Triggers:
    div_trg AFTER INSERT ON operand FOR EACH ROW EXECUTE FUNCTION div_proc()

#まとめ
 トリガとトリガプロシージャを使用することで、あるテーブルにINSERTしたときに、自動で他のテーブルにINSERTすることができました。
 最後まで読んでくださり、ありがとうございました!!

#参考
PostgreSQL11マニュアル(トリガ関数)
https://www.postgresql.jp/document/11/html/plpgsql-trigger.html
PostgreSQL11マニュアル(CREATE TRIGGER)
https://www.postgresql.jp/document/11/html/sql-createtrigger.html

28
17
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
28
17

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?