更新父标准对象在APEX中从子级获取总和值

时间:2014-05-15 01:47:32

标签: object collections salesforce apex soql

我是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。

提前致谢并等待您的积极响应。

1 个答案:

答案 0 :(得分:0)

  1. 我假设您的组织中没有启用货币(如果您在对象的某处看到“CurrencyIsoCode”,则需要稍微修改此设计)。
  2. 我是一个懒惰的人,你没有写任何关于你期望的数据量的东西。当每次接触有合理数量的机会时,我所写的内容将起作用。如果您将开始达到50K查询行的调控器限制,则必须以不同方式完成(我将在最后写一些关于它的内容)。
  3. 我不打算给你一个现成的解决方案,因为“自制汇总摘要”是您在SF DEV 501认证期间可能遇到的任务之一。我只想概述一些指示和思考的食物。
  4. 我不会这样做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)。

    另一种方法是在此汇总摘要中接受一些延迟并为其编写批处理作业。