Explain about “Too Many SOQL Error: 101”
“System.LimitException: Too many SOQL queries: 101”
This error occurs when you exceed SOQL queries governor limit. The actual limit is “you can run up to a total of 100 SOQL queries in a single call or context”.
How to resolve this “Error: System.LimitException: Too many SOQL queries: 101”
- To fix the issue, change your code so that the number of SOQL fired is less than 100.
- If you need to change the context, you can use @future annotation which will run the code asynchronously.
- Avoid SOQL queries that are inside FOR loops.
Follow the key coding principals for Apex Code:
1. Avoid SOQL queries inside For loop.
trigger accountTestTrggr on Account (before insert, before update)
{
//This queries all Contacts related to the incoming Account records in a
// single SOQL query.
//This is also an example of how to use child relationships in SOQL
List<Account> accountsWithContacts = [select id, name, (select id, salutation,
description, firstname, lastname, email from Contacts) from Account where Id
IN :Trigger.newMap.keySet()];
List<Contact> contactsToUpdate = new List<Contact>{};
// For loop to iterate through all the queried Account records
for(Account a: accountsWithContacts)
{
// Use the child relationships dot syntax to access the related Contacts
for(Contact c: a.Contacts)
{
System.debug('Contact Id[' + c.Id + '], FirstName[' + c.firstname + '],
LastName[' + c.lastname +']');
c.Description = c.salutation + ' ' + c.firstName + ' ' + c.lastname;
contactsToUpdate.add(c);
}
}
//Now outside the FOR Loop, perform a single Update DML statement.
update contactsToUpdate;
}
2. Use @future Appropriate.
trigger accountTestTrggr on Account (before insert, before update)
{
//This queries all Contacts related to the incoming Account records in a
// single SOQL query.
//This is also an example of how to use child relationships in SOQL
List<Account> accountsWithContacts = [select id, name, (select id, salutation,
description, firstname, lastname, email from Contacts) from Account where Id
IN :Trigger.newMap.keySet()];
List<Contact> contactsToUpdate = new List<Contact>{};
// For loop to iterate through all the queried Account records
for(Account a: accountsWithContacts)
{
// Use the child relationships dot syntax to access the related Contacts
for(Contact c: a.Contacts)
{
System.debug('Contact Id[' + c.Id + '], FirstName[' + c.firstname + '],
LastName[' + c.lastname +']');
c.Description = c.salutation + ' ' + c.firstName + ' ' + c.lastname;
contactsToUpdate.add(c);
}
}
//Now outside the FOR Loop, perform a single Update DML statement.
update contactsToUpdate;
}
2. Use @future Appropriate.
trigger accountAsyncTrigger on Account (after insert, after update)
{
//By passing the @future method a set of Ids, it only needs to be
//invoked once to handle all of the data.
asyncApex.processAccount(Trigger.newMap.keySet());
}
Here is the Apex class that defines the @future method:
global class asyncApex
{
@future
public static void processAccount(Set<Id> accountIds)
{
List<Contact> contacts = [select id, salutation, firstname, lastname,
email from Contact where accountId IN :accountIds];
for(Contact c: contacts)
{
System.debug('Contact First Name and Last Name: '+c.firstname+'
'+c.lastname);
c.Description = c.salutation + ' ' + c.firstName + ' ' + c.lastname;
}
update contacts;
}
}
Comments
Post a Comment