A common development pitfall is the assumption that trigger invocations
never include more than one record. Apex triggers are optimized to operate in bulk, which, by definition,
requires developers to write logic that supports bulk operations.
This is an example of a flawed programming pattern. It assumes
that only one record is pulled in during a trigger invocation. While
this might support most user interface events, it does not support
bulk operations invoked through the
SOAP API or
Visualforce.
trigger MileageTrigger on Mileage__c (before insert, before update) {
User c = [SELECT Id FROM User WHERE mileageid__c = Trigger.new[0].id];
}
This is another example of a flawed programming pattern. It assumes
that less than
100 records are pulled in during a trigger invocation. If more
than
20 records are pulled into this request, the trigger would exceed
the SOQL query limit of
100 SELECT statements:
trigger MileageTrigger on Mileage__c (before insert, before update) {
for(mileage__c m : Trigger.new){
User c = [SELECT Id FROM user WHERE mileageid__c = m.Id];
}
}
For more information on governor limits, see
Execution Governors and Limits.
This example demonstrates the correct pattern to support the bulk nature of triggers while
respecting the governor
limits:
Trigger MileageTrigger on Mileage__c (before insert, before update) {
Set<ID> ids = Trigger.newMap.keySet();
List<User> c = [SELECT Id FROM user WHERE mileageid__c in :ids];
}
This pattern respects the bulk nature of the trigger by passing
the Trigger.new collection
to a set, then using the set in a single SOQL query. This pattern
captures all incoming records within the request while limiting the
number of SOQL queries.
Best Practices for Designing
Bulk Programs
The following are the best practices for this
design pattern:
- Minimize the number of data manipulation language (DML) operations
by adding records to collections and performing DML operations against
these collections.
- Minimize the number of SOQL statements by preprocessing records
and generating sets, which can be placed in single SOQL statement
used with the IN clause.