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
shaan85shaan85 

Too many script statements:

Hi,

I have an apex class which is being called in the Apex trigger. When the trigger is being fired an error is being thrown :

Too many Script Statements 200001.

How to avoid this? I have followed the best practices to avoid this even then i am not able to avoid this.

 

Here is my code:

 

trigger TestTrigger1 on Obj__c(after insert, after update)

{

set<Id> cntctIds = new set<Id>();

List<obj__c> list2 = new List<obj__c>();

List<obj__c> list3 = new List<obj__c>();

List<obj__c> list1=[select id,Contact__c, field1, field2,.... from obj__c where id In:trigger.newMap.keyset()];

for(Integer j=0;j< list1.size();j++)
    {
        cntctIds.add(list1[j].Contact__c);
    }

objCntct = [select field1,field2 from obj__c where Contact__c IN:cntctIds];

list2 = [select field1,field2 from obj__c where Contact__c IN:cntctIds and field1 = '123'];

list3 = [select field1,field2 from obj__c where Contact__c IN:cntctIds and field1 = ''456];

for(Integer k=0;k< objCntct.size();k++)

{

for(Integr l=0;l<list2.size();l++)

{

//code goes here...

}

 

}

}

 

 

i am doing anything wrong here?

I feel the only reason could be that i am using nested for loops so there might be infinite loops.

Or how to make use of maps to use in loops?

How to avoid this does any one have soln?

 

Thanks

Shaan

_Prasu__Prasu_

Yes, that is due to loop with loop.

using maps will depend upon the conditional matching you required in the loops.

shaan85shaan85

Thanks for the reply..

but can we avoid the loops with the help of Maps.

Because i am  not able to figure out using maps.

Please give some examples to handle this...

_Prasu__Prasu_

Could you post some more code here?

 

Thanks,

shaan85shaan85

Ok, here is my code

 

trigger TestTrigger1 on Obj__c(after insert, after update)

{

set<Id> cntctIds = new set<Id>();

List<obj__c> list_Total = new List<obj__c>();

List<obj__c> list2 = new List<obj__c>();

List<obj__c> list3 = new List<obj__c>();

List<obj__c> list1=[select id,Contact__c, field1, field2,.... from obj__c where id In:trigger.newMap.keyset()];

for(Integer j=0;j< list1.size();j++)
    {
        cntctIds.add(list1[j].Contact__c);
    }

objCntct = [select field1,field2 from obj__c where Contact__c IN:cntctIds];

 

//query retrieves total records

list_Total = [select field1,field2,Status__c from obj__c where Contact__c IN:cntctIds];

 

//query retrieves only terminated records

list2 = [select field1,field2,Status__c from obj__c where Contact__c IN:cntctIds and Status__c= 'Terminated'];

 

//query retrieves only current records

list3 = [select field1,field2,Status__c from obj__c where Contact__c IN:cntctIds and Status__c= 'Current'];

 

for(Integer k=0;k< objCntct.size();k++)

{

     // condition if all the records are Terminated

     if(list_Total.size() == list2.size())

     {

         for(Integr l=0;l<list2.size();l++)

        {

             //code goes here...

             //Contact values are populated here based on some condition checks...

             objCntct[k].field2 = list2[l].field2;

             .....

        }

    }

    // Condition if all records are current.

    if(list_Total.size() == list3.size())

    {

       for(Integr l=0;l<list3.size();l++)

       {

            //code goes here...

            objCntct[k].field2 = list3[l].field2;         

            .....

       }

    }

}

update objCntct;

}

 

Here in the code above based on the conditions  i am populating the contact fields from custom obj and at the end i am updating the contact .

For each condition there is a for loop return and there is the existing main for loop of contact . i guess this might be cause of the error.

 

But how to solve this?

Please let me know if any soln...

 

Thanks

shaan

 

sfdcfoxsfdcfox

Your code is unnecessarily complex, and I'm not quite following your intent. Are you updated all contacts if all Obj__c are terminated? Or is it supposed to be if all objects on one contact are terminated? If you're looking to update each contact based on their children records, you might find it easier to do the following:

 

 

trigger TestTrigger1 on Obj__c(after insert, after update)
{
	Set<Id> set_ContactIds = new Set<Id>();
		for(Obj__c obj:Trigger.new)
			set_ContactIds.add(obj.Contact__c);
			
	List<Contact> contacts = new List<Contact>();
	
	for(Contact c:[select id,(select id,field__c,field2__c,status__c from objs__r where status__c in ('terminated','current')])
	{
		Integer current = 0, terminated = 0;
		for(Obj__c obj:c.objs__r)
			if(objs.status__c=='Current')
				current++;
			else
				terminated++;
		if(c.objs__r.size()==current)
		{
			// ALL RECORDS FOR THIS CONTACT ARE CURRENT
			c.field__c = c.objs__r[0].field__c;
			// ... more stuff
		}
		if(c.objs__r.size()==terminated)
		{
			// ALL RECORDS FOR THIS CONTACT ARE TERMINATED
			c.field2__c = c.objs__r[0].field2__c;
			// ... more stuff
		}
		// add this contact to be updated
		contacts.add(c);
		
	}
	update contacts;
}

 

In this code, I find all contacts (remember, you're in a trigger, so you don't have to query Obj__c for any information on any record included in an insert/update, because all fields will have their current database values). Next, we do a query to find all contacts with their respective Obj__c records (use the "relationship name" from the lookup field to determine the name to use for the query, remembering to add "__r"). Finally, iterate through the objects and perform your logic based on the results. In this example, we don't use any maps, only two queries (sub-queries count as one additional query), and the results are automatically structured for us in a way that we don't have to iterate through very long lists more than once to get our results.

 

 

In general, most triggers will be in this form: Gather a list of values for a query, iterate through a query result, and then perform any final logic. This sort of structure is generally an O(n) algorithm, meaning that the number of elements involved will scale your script usage linearly. Placing a for-loop that covers an entire array inside of another for-loop that covers an entire array creates an O(m*n) or O(n^2) algorithm, which scales very quickly. For example, if you have 5 contacts with 5 objects each, your algorithm would approach 5^3 script iterations, or 125. Adding a sixth contact adds at minimum another 25 executions, assuming that the new contact had no objects of its own. By using a series of maps or a sub-query, the same 5 contacts with 5 objects each has effectively 25 iterations instead of 125.