<DAY215>もう一度トリガーについて
●9/24(火)
●学習日数 215日
●学習時間(本日)6時間
●累計学習時間 914.0時間
●一日あたりの平均学習時間 4.28時間
beforeとafterの違い
before はトリガの実行が先。実行後にシステムによって保存されます。DML の挿入または更新操作を明示的にコールせずに、トリガのレコードを変更できる。
これらのレコードに DML ステートメントを実行すると、エラーが表示されます。
DB保存後にトリガー実行させるafterの場合は明示的なDML操作が必要。
ややこしいので、
SOQLでクエリを引っ張ってる時はafterとの認識で間違いないと思っている。
この時に重要なのがこのDML操作をforループ内で行わない事。ガバナ制限がかかり、エラーとなる可能性が高い。
そのため、以下のような記述が一般的となる。
List<Task> hoges = new List<Task>(); for(Opportunity a : trigger.new){ hoges.add(new Task(Subject='Follow UP Test Task', WhatId=a.Id)); System.debug(a.Probability); } //forから外しておく insert hoges;
トリガーで迷った結論できないと判断したこと。
(1)リレーションを使ってコンテキスト変数経由でデーターを引っ張ること。
取引先オブジェクトに入っている項目を使う場合(できる)
for(Account a : Trigger.New) { //従業員の数が10人以上なら if (a.NumberOfEmployees >10) { oppList.add(new Opportunity(Name=a.Name + ' Opportunity', StageName='Prospecting', CloseDate=System.today().addMonths(1), AccountId=a.Id)); } }
取引先責任者オブジェクトに入っている項目を使う場合(できない)
紐付けでデーター取れるのかなと思ったけど無理。
取り出せたデーター(できる)
//数値 if (a.NumberOfEmployees >10) //テキスト() if (a.AccountNumber =='aaa') //選択リスト if (a.Type =='Prospect') //チェックボックス if (a.check__c ==true) //通貨 if (a.AnnualRevenue ==111) //日付 dateクラスを参照 if (a.SLAExpirationDate__c.day() == 21) //電話 任意の文字列を受け取り、数値を返す if (a.Phone == '555-555-5555') //コンテンツ 文字列で受け取る if (a.TickerSymbol == '555-555-5555')
取り出せないデーター(できない)
参照関係があるかどうかなど。 もし参照関係が空白ならばとかは無理。
mapを使う事例
IDに紐づいているかどうかを確認するために必要である。
(1)レコードに紐づいている、IDの数を数えて、件数を数えたい時。
(2)商談のIDとタスクのIDをSELECTで取り出す。(商談オブジェクトから)
(3)IDをバインド変数を用いてtirgger.newとバインドさせる。
レコードを繰り返しチェックしていくわけだが、そのIDと紐づいているかをみるためにMapが必要。
Listだとこれはできない。
Map<Id,Opportunity> oppsWithOpps = new Map<Id,Opportunity>( [SELECT Id,(SELECT Id FROM tasks) FROM Opportunity WHERE Id IN :Trigger.New ]); for(Opportunity a : Trigger.New) { //生成したレコードのIDを取り出し数が0かどうかを見ている。(関連データーがない事を見ている) if(oppsWithOpps.get(a.Id).Tasks.size() == 0){