1

I did a bit of searching and didn't come up with anything so apologies if this is a duplicate, but -

Situation: I am looking for a way to migrate all related object records from one (bad) account to a new (good) account, programmatically and preferably all at once.

I know that I can get all related objects to the Account object with the Schema.ChildRelationship class, and have done the following in execute anonymous to output a list and get a count:

Map<String, String> childListMap = new Map<String,String>();
List<Schema.Childrelationship> childList = Schema.getGlobalDescribe().get('Account').getdescribe().getChildRelationships();
for(Schema.ChildRelationship cr : childList){
    //system.debug(cr.getChildSObject());
    //system.debug(cr.getField());
    childListMap.put(String.valueOf(cr.getChildSObject()),String.valueOf(cr.getField()));
}
System.debug(childListMap.size());
for(String s : childListMap.keySet()){
    System.debug('Obj: ' + s + ' Field: ' + childListMap.get(s));
}

However, this is yielding a total of 91 objects related to the account. Some of them (I presume) are read only/system objects anyway, but the Schema class returns them - things like:

  • AccountBrand
  • AccountFeed
  • AccountHistory
  • AccountPartner
  • AccountShare
  • etc

I believe my only way to handle the next step would be to loop through the list of every SObject in my map and do individual queries inside the loop and store them to a separate map if they yield more than one result, so that I could then use that other map to update the object(s), something like this (note, this code is untested, just example):

String obj,field;
String queryString;
Map<String,List<SObject>> objMap = new Map<String,List<SObject>>();
for(String s : childListMap.keySet()){
    obj = s;
    field = childListMap.get(s);
    queryString = 'SELECT ' + field + ' FROM ' + obj + ' WHERE ' + field + ' = ' + accId;
    List<SObject> objResult = Database.query(queryString); 
    if(obj.size() > 0){
        objMap.put(obj,objResult);    
    }
}

Problem/Question: That of course would be 91 SOQL queries, pretty close to our limit without even considering other code that might run as a result of the record update(s). So ultimately my question is, is there any better way to accomplish this? Any way for me to optimize my original Schema call to limit the results to only tangible objects or to exclude obvious system objects that I have no use for in this process? Any way for me to query for all of the records from multiple objects simultaneously instead of looping through and doing queries in the loop? Not really looking for someone to debug my code (yet!) so much as I am looking for any suggestions on how I may make this better, if possible.

5

It sounds like you want to merge two records. The Database.merge method (or the merge DML keyword) will move all children from the bad account to the good account, and delete the bad account. If you want to keep the bad account, you can simply call Database.undelete (or the undelete DML keyword) on the bad account afterwards; all of the children affected will remain with the new account, as a merge cannot be undone.

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.