For Loops
Apex supports three variations of the for loop:
• The traditional for loop:
for (init_stmt; exit_condition; increment_stmt) { code_block
}
• The list or set iteration for loop:
for (variable : list_or_set) { code_block
}
where variable must be of the same primitive or sObject type as list_or_set.
• The SOQL for loop:
for (variable : [soql_query]) { code_block
}
or
for (variable_list : [soql_query]) { code_block
}
Both variable and variable_list must be of the same sObject type as is returned by the soql_query.
Note: Curly braces ({}) are required around a code_block only if the block contains more than one statement.
Each is discussed further in the sections that follow.
Traditional For Loops
The traditional for loop in Apex corresponds to the traditional syntax used in Java and other languages. Its syntax is:
for (init_stmt; exit_condition; increment_stmt) { code_block
}
When executing this type of for loop, the Apex runtime engine performs the following steps, in order:
1. Execute the init_stmt component of the loop. Note that multiple variables can be declared and/or initialized in this statement.
2. Perform the exit_condition check. If true, the loop continues. If false, the loop exits.
3. Execute the code_block.
Loops
4. Execute the increment_stmt statement.
5. Return to Step 2.
As an example, the following code outputs the numbers 1 - 10 into the debug log. Note that an additional initialization variable, j, is included to demonstrate the syntax:
for (Integer i = 0, j = 0; i < 10; i++) { System.debug(i+1);
}
List or Set Iteration For Loops
The list or set iteration for loop iterates over all the elements in a list or set. Its syntax is:
for (variable : list_or_set) { code_block
}
where variable must be of the same primitive or sObject type as list_or_set.
When executing this type of for loop, the Apex runtime engine assigns variable to each element in list_or_set, and runs the code_block for each value.
For example, the following code outputs the numbers 1 - 10 to the debug log:
Integer[] myInts = new Integer[]{1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
for (Integer i : myInts) { System.debug(i);
}
SOQL For Loops
SOQL for loops iterate over all of the sObject records returned by a SOQL query. The syntax of a SOQL for loop is either:
for (variable : [soql_query]) { code_block
}
or
for (variable_list : [soql_query]) { code_block
}
Both variable and variable_list must be of the same type as the sObjects that are returned by the soql_query. As in standard SOQL queries, the [soql_query] statement can refer to script expressions in their WHERE clauses using the : syntax. For example:
String s = 'Acme';
for (Account a : [select id, name from account where name like :(s+'%')]) { // Your code
}
Loops
The following example combines creating a list from a SOQL query, with the DML update method.
// Create a list of account records from a SOQL query
List<Account> accs = [SELECT Id, Name FROM Account WHERE Name = 'Siebel'];
// Loop through the list and update the Name field for(Account a : accs){
a.name = 'Oracle';
}
// Update the database update accs;
SOQL For Loops Versus Standard SOQL Queries
SOQL for loops differ from a standard SOQL statements because of the method they use to retrieve sObjects. While the standard queries discussed in SOQL and SOSL Queries can retrieve either the count of a query or a number of object records, both limited by the maximum size of a list (1,000), SOQL for loops retrieve all sObjects, using efficient chunking with calls to the query and queryMore methods of the Force.com Web Services API. Consequently, developers must always use a SOQL for loop to process query results that return more than 1,000 records.
SOQL For Loop Formats
SOQL for loops can process records one at a time using a single sObject variable, or in batches of 200 sObjects at a time using an sObject list:
• The single sObject format executes the for loop's <code_block> once per sObject record. Consequently, it is easy to understand and use, but is grossly inefficient if you want to use data manipulation language (DML) statements within the for loop body. Each DML statement ends up processing only one sObject at a time.
• The sObject list format executes the for loop's <code_block> once per list of 200 sObjects. Consequently, it is a little more difficult to understand and use, but is the optimal choice if you need to use DML statements within the for loop body. Each DML statement can bulk process a list of sObjects at a time.
For example, the following code illustrates the difference between the two types of SOQL query for loops:
// Create a savepoint because the data should not be committed to the database Savepoint sp = Database.setSavepoint();
insert new account[]{new account(name = 'yyy'), new account(name = 'yyy'), new account(name = 'yyy')};
// The single sObject format executes the for loop once per returned record Integer I = 0;
for (account tmp : [select id from account where name = 'yyy']) { i++;
}
System.assert(i == 3); // Since there were three accounts named 'yyy' in the // database, the loop executed three times
// The sObject list format executes the for loop once per returned batch // of records
i = 0;
Integer j;
for (account[] tmp : [select id from account where name = 'yyy']) { j = tmp.size();
i++;
}
System.assert(j == 3); // The list should have contained the three accounts // named 'yyy'
System.assert(i == 1); // Since a single batch can hold up to 100 records and, // only three records should have been returned, the // loop should have executed only once
Loops
// Revert the database to the original state Database.rollback(sp);
Note:
• The break and continue keywords can be used in both types of inline query for loop formats. When using the sObject list format,continue skips to the next list of sObjects.
• DML statements can only process up to 200 records at a time, and sObject list for loops process records in batches of 200. Consequently, if you are inserting, updating, or deleting more than one record per returned record in an sObject list for loop, it is possible to encounter runtime limit errors. See Understanding Execution Governors and Limits on page 142.