我是Apex的新人。我想在before insert
的顶点写一个触发器。我有两个标准对象(联系人,机会)。
SELECT sum(amount), Bussiness__c FROM opportunity
WHERE stagename='Closed Won' and id='006i000000Kt683AAB' GROUP BY Bussiness__c
我想在触发器运行此获取总和(金额)字段和Bussiness__c值时,然后使用Sum(Amount)值更新Contact Total_Business__c。这里Bussiness__C是机会对象的联系人ID。
提前致谢并等待您的积极响应。
答案 0 :(得分:0)
我不会这样做before insert
,在after insert, after update
中更容易(你在金额变化时没有考虑重新计算,是吗?)。如果允许您的用户删除商机,也应该说after delete, after undelete
。
首先要建立一套“我们必须重新计算的联系人”:
Set<Id> contactIds = new Set<Id>();
for(Opportunity o : trigger.old){
contactIds.add(o.Business__c);
}
for(Opportunity o : trigger.new){
contactIds.add(o.Business__c);
}
contactIds.remove(null);
这会强制重新计算所有相关联系人,并在没有联系的情况下忽略机会。它总会点火......这不是最好的事情,因为在插入,删除,取消删除时你总是希望它一直触发但是在更新时你只想在数量或接触发生变化时触发它(trigger.old将保持不同的联系而不是trigger.new)。您可以使用Trigger.isUpdate
之类的内容控制这些方案,然后阅读相关内容。
无论如何 - 你有一套独特的联系人ID。我已经说过我会在“之后”触发器中执行此操作,因为此时新的Amount已经保存到数据库中,您可以从中查询它:
SELECT Business__c, SUM(Amount) sumAmount
FROM Opportunity
WHERE Business__c IN :contactIds
这种类型的查询返回一个“AggregateResult”,您必须像这样解析:
List<Contact> contactsToUpdate = new List<Contact>();
for(AggregateResult ar : [SELECT Business__c, SUM(Amount) sumAmount
FROM Opportunity
WHERE Business__c IN :contactIds]){
System.debug(ar);
contactsToUpdate.add(new Contact(Id = (Id) ar.get('Business__c'),
Total_Business__c = (Double) ar.get('sumAmount)
);
}
update contactsToUpdate;
正如我所说 - 这是一个基本的大纲,应该让你开始。
这件事查询给定联系的所有机会。你的触发器最多可以触发200个Opps。想象一下你改变所有200个操作的联系方式的情况 - &gt;为您提供400个联系人,您需要更新以清除/修复旧值并设置新值。如果没有触发50K行限制,假设没有触发其他业务逻辑(比如更新账户?因为添加了一些商机产品而启动的操作?),当平均每次接触涉及125个Opp时,就会出现问题。这听起来像一个荒谬的问题,但有些情况下你需要采用不同的方式。
在这种情况下,你可以从另一个角度攻击它。你真的不需要查询给定联系人的所有opps,它是懒惰的。您可以学习总业务的当前值(如果它恰好为空,则输入0)然后根据需要添加/减去所有更改,只查看您的trigger.old和trigger.new。它可以提供更多代码和更多计划,但性能将显着提高,此解决方案将随着opps数量的增长而扩展(它将继续仅查看触发器范围内当前最大200 opps)。
另一种方法是在此汇总摘要中接受一些延迟并为其编写批处理作业。