This is a common mistake where queries or DML statements are placed inside a for loop to lookup a record once per iteration. By doing this you will very quickly hit the governor limit of SOQL queries and/or DML statements (insert, update, delete, undelete).
Instead, move any database operations outside of for loops. Form a single query such that you get all the required records at once. You can then iterate over the results. If you need to modify the data, batch update into a list and invoke your DML once for that list of data.
Here is an example showing both a query and a DML statement inside a for loop:
trigger accountTestTrggr on Account (before insert, before update) {
//For loop to iterate through all the incoming Account records
for(Account a: Trigger.new) {
//THE FOLLOWING QUERY IS INEFFICIENT AND DOESN'T SCALE
//Since the SOQL Query for related Contacts is within the FOR
//loop, if this trigger is initiated with more than 100 records,
//the trigger will exceed the trigger governor limit of maximum
//100 SOQL Queries.
List contacts = [select id, salutation, firstname,
lastname, email from Contact where accountId = :a.Id];
for(Contact c: contacts) {
System.debug('Contact Id[' + c.Id + '], FirstName['
+ c.firstname + '], LastName[' + c.lastname +']');
c.Description = c.salutation + ' ' + c.firstName + ' '
+ c.lastname;
//THIS FOLLOWING DML STATEMENT IS INEFFICIENT AND DOESN'T
//SCALE Since the UPDATE dml operation is within the FOR
//loop, if this trigger is initiated with more than 150
//records, the trigger will exceed the trigger governor limit
//of 150 DML Operations maximum.
update c;
}
}
}
Since there is a SOQL query within the for loop that iterates across all the Account objects that initiated this trigger, a query will be executed for each Account. An individual Apex request gets a maximum of 100 SOQL queries before exceeding that governor limit. So if this trigger is invoked by a batch of more than 100 Account records, the governor limit will throw a runtime exception.
In this example, because there is a limit of 150 DML operations per request, a governor limit will be exceeded after the 150th contact is updated.
Here is the optimal way to efficiently query the contacts in a single query and only perform a single update DML operation:
trigger accountTestTrggr on Account (before insert, before update) {
//In this case we are using the child relationships to filter down
//and form a single query to get the required records.
List accountsWithContacts = [select id, name, (select id,
salutation, description, firstname, lastname, email from Contacts)
from Account where Id IN :Trigger.newMap.keySet()];
List contactsToUpdate = new List{};
// For loop to iterate through all the queried Account records
for(Account a: accountsWithContacts){
// Use the child relationships 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;
}
Now if this trigger is invoked with a single account record or up to 200 account records, only one SOQL query and one update statement is executed.