今回は、「before insertとafter insertの使いわけ」について確認していきます。
まずは、それぞれのトリガの特性を見ていきましょう。
「before insert」と「after insert」の特性
下の表は、「before insert」と「after insert」の特性を示しています。
起動タイミング | trigger.newの項目値の変更 | システム情報(Idや作成日時)の使用 | |
---|---|---|---|
before insert | DBに保存される前 | 〇 | × |
after insert | DBに保存された後 | × | 〇 |
before insert とafter insertの違いは「トリガ起動のタイミング」、「 Trigger.newの値の変更」、「システム情報の使用」の3つのポイントに大別することができます。
1つずつ見ていきます。
トリガ起動タイミング
まず、before insert とafter insertの大きな違いは、トリガの起動タイミングです。
before insertトリガは、レコードが新規作成され、DBに保存される前に起動し、afterトリガは、レコードがDBに保存された後(コミットはされていない)に起動します。
順番としては、before insert → レコードのDBへの保存 → after insert、といった感じです。
Trigger.newの値の変更
before insertでは、Trigger.newの値をDBに保存される前に変更することができます。
Trigger.newというのは、トリガコンテキスと呼ばれるもので、ここではinsertされたレコードのリストと考えてもらえると理解しやすいと思います。
なぜ、before insertではTrigger.newの値(新しく作成されたレコードの値)を変更できるかというと、レコードがDBに保存される前に実行されるからです。
レコードがDBに保存された後だと、新規作成したレコードにはそれぞれIdが割り振られるため、そのレコードに対して変更を加えるためには、レコードのIdを一度取得する必要があります。
どうせ新規作成したレコードの値を変更するならそんな面倒な処理は省きたいですよね?
そこで面倒なIdの取得をしなくとも、直接insertレコードを変更することができるbefore insertを使用するわけです。
システム情報の利用
after insertは、レコードがDBに保存され、Idや作成者、作成日などが付与された後に起動するため、それらのシステム情報を処理内で利用することが可能です。
それに対しbefore insertは、レコードがDBに保存される前に起動するため、そのレコードのIdや作成日などのシステム情報を利用知ることができません。
なぜならそれらのシステム情報は、DBに保存されることで初めてレコードに付与されるものだからです。
そして、Idが付与されるということは、作成されたレコードを他のオブジェクトの参照/主従関係の項目値として利用することもできるわけです。
また、Idをキーに設定するTrigger.newMapの利用もafter insertでは可能です。
まとめ:before insertとafter insertの使いわけ
さて、ではどんな時にbefore insertを使用して、どんな時にafter insertを使用すればいいのかという話ですが、
ざっくりまとめるとこんな感じになります。
- 作成したレコードの値を変更(Trigger.newを変更)したい
- 入力規則のチェックより前に処理を実行したい
⇒ before insert
- システム情報を利用したい
- 他のオブジェクトの参照/主従関係項目として利用したい
- Trigger.newMapを利用したい
⇒ after insert
コメント