I have a contact list I am looping over and one of the fields in the contact object holds 1 or more contactIDs in a delimited list using a carriage return.

Standard Contact Object:

ContactId: 0030W00003kuP8bQAE



ContactId: 0030W00003kuP8bABX


My end goal is that anywhere that the PastContactId is found on ExternalCustomObject, I need to update it to the corresponding Current ContactId (ContactId).

example pseudo code:

UPDATE ExternalCustomObject SET CurrentContactID = ContactId WHERE CurrentContactID IN PastContactId


UPDATE ExternalCustomObject SET CurrentContactID = '0030W00003kuP8bABX' WHERE CurrentContactID IN ['0030W00003kuP8RDEF', '0035400000WqTx3JKL']

The big piece here is that the list of contacts is varying so I don't think this update should be done within a loop.

I am just having trouble figuring out how to structure this so that it can build an update statement that I can run against the ExternalCustomObject at the end, and not during the iteration.

I thought about trying something like this where it builds out an array/list and try and iterate that, but I think it would still require the update to be done within a loop and I don't know if that's frowned upon.

    '0030W00003kuP8bQAE', ['0030W00003kuP8RQAU', '0035400000WqTx3AAF'],
    '0030W00003kuP8bABX', ['0030W00003kuP8RDEF', '0035400000WqTx3JKL']

Any thoughts on how to approach this?

Example of a very pseudo attempt of my thinking:

// Source contact list that we will have for a merge
List<Id> sourceContacts = new List<Id>();

// Final list that will hold the current and all past Contact Ids
List<Id> finalList = new List<Id>();

try {
    // Loop over contacts
    for (Contact con : [Select PastContactIDs__c FROM Contact WHERE Id IN :sourceContacts]){

        // Split the dupId field into a list
        List<String> dupId = con.PastContactIDs__c.split('\n');

        // If we have data in the list, continue
        if(dupId.size() > 0){

            // Can we add both the ContactID and the PastContactIDs to a list here so that we can build an update statement for later on?
            for (String dup: dupId){

    // Do we have data we need to update?
    if(finalList.size() > 0){

        // Attempt to update the external object

            // Do update Here

        } catch(exception e){


} catch (exception e) {

1 Answer 1

// Build xref map - assumes a given pastContactId refers to 1 and only 1 Contact 
Map<Id,Contact> contactsByPastContactId = new Map<Id,Contact>();
for (Contact c : contacts) {
  for (String pastContactId : c.PastContactIds__c != null
           ? c.PastContactIds__c.split('\n') : new List<String>() {
      contactsByPastContactId.put((Id)pastContactId,c);  // build xref

// Fetch objects to update
External_Custom_Obj__c[] extObjs = [SELECT Id FROM External_Custom_Obj__c 
                                     WHERE CurrentContactId__c IN : contactsByPastContactId.keySet()];

// for each external obj, use the xref map to find the new value
for (External_Custom_Obj__c extObj : extObjs) {
    extObj.CurrentContactId__c = contactsByPastContactId.containsKey(extObj.CurrentContactId__c) 
        ? contactsByPastContactId.get(extObj.CurrentContactId__c).Id
        : extObj.CurrentContactId__c;

update extObjs; 

Note the use of collections for every operation and no need to test for null

  • Thank you, I will try and see if I can integrate this. The only difference is that my source contacts would be more than one, with each of those having a varying amount of these past contact ids.
    – SBB
    Mar 25, 2020 at 17:34
  • I believe I modeled that requirement
    – cropredy
    Mar 25, 2020 at 20:24

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .