You need to sign in to do that
Don't have an account?
20 query limiter on a Trigger
Hi All,
need you help with a trigger i have that is fired when the Contract.Renewal_Negotiators__c field is inserted or updated the trigger then populates the Sales_Employees__c field which is a lookup field to the User object.
The trigger works on a manual process but i had to put in the following code to allow me to update all records in the Contracts object : -
//Not to fire Trigger if user is equal to 'Admin Name'
if (UserInfo.getName()<> 'Admin name')
i am hitting the governer limits if i take off the above code... i know the logic is in correct and that i need to take this out of the for loop.
Problem is that i not sure how to amend my code below so i don't hit the limits... can someone help me by re-writing the code below so i don't hit the limiters?
Thanks.
Sean.
trigger Sales_Manager_Trigger on Contract__c (before insert, before update) { for (Contract__c Contract : Trigger.new) { //Not to fire Trigger if user is equal to 'Admin Name' if (UserInfo.getName()<> 'Admin name') { Contract.Sales_Manager__c = null; List <Sales_Employees__c> arrRenNegs = new list <Sales_Employees__c>(); arrRenNegs = [select name from Sales_Employees__c where ID = :Contract.Renewal_Negotiators__c]; if (arrRenNegs.size()>0) { List <user> arrUsers = new List <user>(); arrUsers = [select ID from User where Name = :arrRenNegs.get(0).Name]; if (arrUsers.size()>0) { Contract.Sales_Manager__c = arrUsers.get(0).ID; } } } } }
Okay let's sort this baby out. I'm sure this is more or less what you're trying to do,
For every execution of the trigger you will execute 2 SOQL queries. If this is the only trigger firing you are well within your limits. If you pass 10000000000 records to the trigger - which isn't possible - but if you could only 2 queries would execute. This solves the question originally posed in this post.
You also mentioned you'd like the trigger to run over 12 000 records, but you may have to batch as that limit can cause more than one type of govenor limit exception. How is the update being initialised? If you can break it into thirds you should be okay. Another very nifty feature is bulk apex, check that out here: http://salesforcesource.blogspot.com/2010/02/utilizing-power-of-batch-apex-and-async.html
All Answers
You need to optimize your code by bringing SOQL and DML out of your for loops.
trigger Sales_Manager_Trigger on Contract__c (before insert, before update)
{
for (Contract__c Contract : Trigger.new)
{ //Not to fire Trigger if user is equal to 'Admin Name'
if (UserInfo.getName()<> 'Admin name')
{
Contract.Sales_Manager__c = null;
List <Sales_Employees__c> arrRenNegs = new list <Sales_Employees__c>();
arrRenNegs = [select name from Sales_Employees__c where ID = :Contract.Renewal_Negotiators__c];
if (arrRenNegs.size()>0)
{
List <user> arrUsers = new List <user>();
arrUsers = [select ID from User where Name = :arrRenNegs.get(0).Name];
if (arrUsers.size()>0)
{
Contract.Sales_Manager__c = arrUsers.get(0).ID;
}
} } } }
You have to try and remove these SOQL out of the loop by modifying the logic.
Did this answer your question? If not, let me know what didn't work, or if so, please mark it solved.
Hey
I'm not sure what you're doing in the second half of the trigger but the below code will move your queries out of the loop:
Cheers,
Wes
Thanks to both of you...
In terms of the code... below I am getting the list of users and populating the Contract.Sales_Manager__c field with the name of the user
I have taken the you code that you did with the logic but still hitting the limiters??
Any Chance you could help with resolve this??? error was on line 15 column 33
Please...
Thanks.
Hey
Please can you post all of the code you're using, it doesn't seem to make sense because the code that I've posted only runs 2 queries per trigger call.
Wes
Hi weznolte,
below is all the code for my trigger: -
It works when i manually update a single record but when i use the update function Apex Data Loader then i get a error message below: -
arrRenNegs = [select name from BGB_Sales_Employees__c where ID = :bgbContract.Renewal_Negotiators__c];
Line 15 column 26 is shown above after 'arrRenNegs ='
Thanks,
Sean.
Hi Sean
If you take a look at the sample code I gave you there aren't any queries in a loop. If you copy that code you will not encounter this errors. Is there some requirement that my code does not meet?
Wes
Hi weznolte,
i tried you code but got the same error... I have amended the code can you have a look at this and see what the problem may be?
the error i get is the following: -
Which is the same place as below...
trigger Sales_Manager_Trigger on BGB_Contract__c (before insert, before update) { List <BGB_Sales_Employees__c> arrRenNegs = new list <BGB_Sales_Employees__c>(); Set<Id> contractIds = new Set<Id>(); for (BGB_Contract__c bgbContract : Trigger.new) { contractIds.add(bgbContract.Renewal_Negotiators__c); } // close the loop here //Not to fire Trigger if user is equal to 'Sean Churchill' if (UserInfo.getName()<> 'Sean Churchill') { bgbContract.Sales_Manager__c = null; arrRenNegs = [select name from Sales_Employees__c where ID IN :contractIds]; // Since you aren't in a loop this the first query if (arrRenNegs.size()>0) { List <user> arrUsers = new List <user>(); arrUsers = [select ID from User where Name = :arrRenNegs.get(0).Name]; // No loop, so this is query number 2. You have only run 2 queries (this one and the previous) each time the trigger fires. if (arrUsers.size()>0) { bgbContract.Sales_Manager__c = arrUsers.get(0).ID; } } } }
Thanks for your help... I have done what you have said and i get the following error?
"Save error: Expression cannot be assigned"
not sure what this means?? below is the updated code i had to re-declared BGB_contracts__c var as the bgbContract was in the loop.
Any ideas???
here the error:
here the code: -
Take this code and copy and paste it. Don't change anything. If you get an error tell me what it is.
Hi,
I get the following error still after copying your copy and not changing anything: -
??
Thanks for all your help with this... but it doesn't look like this trigger will work on a overnight process of an update of 12,000 records...
Thanks,
sean.
Hi,
The problem is... we need to update an field with in the same contract record - is there any way to get a handle on each individual instance of the contract record, using your method?
Many thanks for all you help,
Sean.
Okay let's sort this baby out. I'm sure this is more or less what you're trying to do,
For every execution of the trigger you will execute 2 SOQL queries. If this is the only trigger firing you are well within your limits. If you pass 10000000000 records to the trigger - which isn't possible - but if you could only 2 queries would execute. This solves the question originally posed in this post.
You also mentioned you'd like the trigger to run over 12 000 records, but you may have to batch as that limit can cause more than one type of govenor limit exception. How is the update being initialised? If you can break it into thirds you should be okay. Another very nifty feature is bulk apex, check that out here: http://salesforcesource.blogspot.com/2010/02/utilizing-power-of-batch-apex-and-async.html
Hi,
I have pasted your code and get the following error message when trying to save the code: -
any ideas??
Thanks, that worked...
I only covering 70% of my test now but cannot get it over the required 75% is it possible for you to help below: -
I'm guessing it's because of this line: