function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
Puja Dev 6Puja Dev 6 

"AccountTrigger: System.LimitException: Apex CPU time limit exceeded" error at the time of bulk data import.

Hi All,

Please help me to bulkiefy the following :

 private void getAccountD(List<Account> acc){
         List<Account> account = new List<Account>();
         List<State_Master__c> SM = [SELECT TerritoryState__c,District__c,Town__c,Zone__c,RO__c,Territory_Code__c FROM State_Master__c];
         for(State_Master__c e : SM){
            for(Account g : acc){
                    if((e.TerritoryState__c == g.State_Name__c) && (e.District__c == g.District__c) && (e.Town__c == g.Town__c)){
                        system.debug('Update Acc');                        
                        g.Sales_Office_Text__c = e.Zone__c;
                        g.Sales_District_Text__c = e.Territory_Code__c;
                        g.Sales_Group_Text__c = e.RO__c;
                        account.add(g);
                    }     
            }
        }
        if(account.size() <= 0){
            for(Account g : acc){
                   g.Sales_Office_Text__c = '';
                   g.Sales_District_Text__c = '';
                   g.Sales_Group_Text__c = '';
                   account.add(g);            
            }
        }  
    }

It is working fine for individual record insert and update event.

But it gives
"AccountTrigger: System.LimitException: Apex CPU time limit exceeded" this error at the time of bulk data import.


Thanks in Advance,
Puja
marktukmarktuk
Unless the inbound list of Accounts is quite large and the query of State_Master__c returns a lot of records, I doubt this method alone is the cause of the CPU time limit being exceeded. It's likely the time limit is being exceeded as a result of other actions on record insert/update such as the Process Builder, workflows and/or managed packages. Do you have many Process Builders on the object where you're seeing the time limit exceeded?
Puja Dev 6Puja Dev 6
Hi Mark,

Yes there are 4 workflow rules on the same object i.e. on Account
 
Ajay K DubediAjay K Dubedi
Hi Puja,
Your Code is throwing the error because your Apex execution time is too long. Salesforce has defined certain governor limits which are to be followed while we code.
The Maximum CPU time on the salesforce servers is 10,000 milliseconds for Synchronous apex and 60,000 milliseconds for Asynchronous apex.
Using nested for loop works fine upto certain limit but it fails for bulk data Load.

Solution:-
1. You can limit the amount of records Queried like below:
    List<State_Master__c> SM = [SELECT TerritoryState__c,District__c,Town__c,Zone__c,RO__c,Territory_Code__c FROM State_Master__c LIMIT 500];
    
2. You can use a Map instead of double for loop.

Thanks,
Ajay
Puja Dev 6Puja Dev 6
hi Ajay,

I have 40000 records for State Master.

Can you please give me any sample code for MAP...?
Or help me to figure out this problem...?
Ajay K DubediAjay K Dubedi
Hi Puja,
Can you brief me about the functionality of your Trigger?
Thanks 
Ajay
Puja Dev 6Puja Dev 6
I have 3 fields on account State, District and Town. and same fields on State Master as well.
State Master contains  Zone__c,Territory_Code__c,RO__c. I have to populate this fields on Account.

 if((e.TerritoryState__c == g.State_Name__c) && (e.District__c == g.District__c) && (e.Town__c == g.Town__c)){
                        system.debug('Update Acc');                        
                        g.Sales_Office_Text__c = e.Zone__c;
                        g.Sales_District_Text__c = e.Territory_Code__c;
                        g.Sales_Group_Text__c = e.RO__c;
                        account.add(g);
                    }     
marktukmarktuk
Okay, so looping over 40000 records is probably more likely to be the source of the issue. Ideally you need to limit that query using a WHERE clause. You'll need to loop through your Account list first and build up some unique sets of values for State_Name__c, District__c & Town__c. You could then use these sets to filter the State_Master__c query to only return the records relevant to the current list of accounts.
v varaprasadv varaprasad
Hi Puja,

Please try once using sets and maps below are sample codes to avoid CPU time limit error.
 
=======1st Option======You can use set ====================
set<String> StateName = new set<String>();
set<String> District = new set<String>();
set<String> Town = new set<String>();

for(Account ac : acc){
StateName.add(ac.State_Name__c);
District.add(ac.District__c);
Town.add(ac.Town__c);
}
       

 list<State_Master__c> SM = [SELECT TerritoryState__c,District__c,Town__c,Zone__c,RO__c,Territory_Code__c FROM State_Master__c where TerritoryState__c in:StateName and District__c in: District and Town__c in: Town];
 
 =======2nd Option======You can use Map ====================
 
 Map <string, State_Master__c> getDistStbyTownMap = new Map <string, State_Master__c>();
 for(State_Master__c st : SM){
     getDistStbyTownMap.put(st.Town__c,st);
}
	 
	 for(Account g : acc){
                  if((getDistStbyTownMap.get(Town__c).TerritoryState__c == g.State_Name__c) && (getDistStbyTownMap.get(Town__c).District__c == g.District__c) && (getDistStbyTownMap.get(Town__c).Town__c == g.Town__c))
==========================================================
Please let me know in case of any other help.

Thanks
Varaprasad