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

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.