首页 > 解决方案 > 使用 Apex 触发器更新相关记录

问题描述

我有以下用例,无法为其编写正确的触发器

在对象帐户上,我们拯救了我们的病人。每个患者都有一名联网的全科医生 (GP)。全科医生保存在对象联系人中。有时,全科医生退休,新的全科医生接管了全科医生的工作,因此与该全科医生有联系的患者必须更换为新的全科医生。

我在 Salesforce 中的对象联系人 2 字段、GPChange__c(布尔值)和 NewGP__c(联系人查找字段)中创建。当用户将布尔字段设置为 true 并填写新的 GP 时,必须运行 Apex 触发器并收集连接到“退休”GP 的所有帐户(患者),并使用来自 NewGP__C 的 ID 更新帐户上的 GeneralPracticioner__c 字段。

这就是我要走多远,它将运行和收集,但不会更新该字段。任何人都可以帮助我吗?

 trigger trgnewGP on Contact (before update) {
    for (Contact mycontact : Trigger.new) {
        if (mycontact.GPChange__c = true && mycontact.NewGP__c != null){
            list <account> gps = [SELECT GeneralPracticioner__c from account
                                    where GeneralPracticioner__c =: mycontact.id];
            for(Account acc : gps){
            if (gps.size() > 0) {
                acc.GeneralPracticioner__c = mycontact.NewGP__c;
            
                    
                    } }
            }
    }
}

标签: salesforceapex

解决方案


该代码中存在一些问题:

  • if (mycontact.GPChange__c = true ...-当心:您分配trueGPChange__c. 请记住,无需编写checkboxField == true,它已经解析为布尔值。
  • 没有 dml,它永远不会更新帐户。
  • 它没有被批量化:您正在循环内进行查询,因此它可能会引发 LimitException(SOQL 查询过多:101)

为了拉出查询,您需要收集退休 GP 的 Id。然后您可以使用 Trigger.NewMap
检索需要更新和设置的帐户记录。GeneralPracticioner__c

trigger trgnewGP on Contact (before update) {
    List<Id> retiredGpIds = new List<Id>();
    for (Contact gp : Trigger.new) {
        if (gp.GPChange__c && gp.NewGP__c != null) {
            retiredGpIds.add(gp.Id);
        }
    }
    
    if (!retiredGpIds.isEmpty()) {
        List<Account> patients = [SELECT GeneralPracticioner__c from Account WHERE GeneralPracticioner__c IN :retiredGpIds];
        for (Account acc : patients) {
            acc.GeneralPracticioner__c = Trigger.NewMap.get(acc.GeneralPracticioner__c).NewGP__c;
        }
        update patients;
    }
}

由于没有更新联系人记录,我将在after update.


更新:

奇怪的是,当我尝试使用 Dataloader [...] 时,它运行良好并且没有任何顶点 CPU 错误。

Dataloader 使用在异步上下文中运行的批量 api,因此它们具有更高的CPU 限制:60 秒 vs 10 秒。

我建议future在触发器处理程序类的方法中提取该触发器的逻辑。
它应该看起来像:

@future
public static void updateGeneralPracticioner(List<Id> retiredGpIds) {
    Map<Id, Contact> gpMap = new Map<Id, Contact>([SELECT Id, NewGP__c FROM Contact WHERE Id IN :retiredGpIds);
    List<Account> patients = [SELECT GeneralPracticioner__c from Account WHERE GeneralPracticioner__c IN :retiredGpIds];
    for (Account acc : patients) {
        acc.GeneralPracticioner__c = gpMap.get(acc.GeneralPracticioner__c).NewGP__c;
    }
    update patients;
}

触发:

trigger trgnewGP on Contact (after update) {
    List<Id> retiredGpIds = new List<Id>();
    for (Contact gp : Trigger.new) {
        if (gp.GPChange__c && gp.NewGP__c != null) {
            retiredGpIds.add(gp.Id);
        }
    }

    if (!retiredGpIds.isEmpty()) {
        ContactTriggerHandler.updateGeneralPracticioner(retiredGpIds);
    }
}

推荐阅读