トリガ・トリガプロシージャの使い方（PostgreSQL）

#トリガ・トリガプロシージャとは
　**トリガ**とは、あるテーブルに対して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のマニュアルを参考にしてください。

```SQL
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 トリガプロシージャ名;**

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

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

```SQL
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 テーブル名**

```sql
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