== Why is this an issue? In order to protect shared resources, Salesforce enforces a maximum number of DML statements which can be executed inside a single https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_transaction.htm[transaction]. This is part of https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_gov_limits.htm[Governor limits]. If a DML statement is nested inside a loop's body (For/While/Do-While) it might be executed more times than the Governor limit allows, making the code fail. Thus it is a best practice to not have DML statements nested in the body of loops and instead perform the DML operation on a list of sObjects. This rule raises an issue when it detects DML statements inside a loop. === Noncompliant code example [source,apex] ---- public class myDMLLoop { public static void myFunction() { for (Task task: [Select Id, subject from Task]) { if (task.subject == 'foo') { task.subject = 'bar'; update task; // Noncompliant } } } } // Query in a while loop public class myDMLLoop { public static void myFunction(Task[] tasks) { Integer i = 0; while ( i < 1000) { Task task = tasks[i]; if (task.subject == 'foo') { task.subject = 'bar'; update task; // Noncompliant } } } } // Query in a do-while loop public class myDMLLoop { public static void myFunction(Task[] tasks) { Integer i = 0; do { Task task = tasks[i]; if (task.subject == 'foo') { task.subject = 'bar'; update task; // Noncompliant } i++; } while (i < 1000); } } ---- === Compliant solution [source,apex] ---- public class myDMLLoop { public static void myFunction() { List updatedTasks = new List(); for (Task task: [Select Id, subject from Task]) { if (task.subject == 'foo') { task.subject = 'bar'; updatedTasks.add(task); } } update updatedTasks; } } ---- == Resources * https://developer.salesforce.com/index.php?title=Apex_Code_Best_Practices&oldid=26951[Apex Code Best Practices] * https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_loops_for_SOQL.htm[SOQL For Loops] ifdef::env-github,rspecator-view[] ''' == Implementation Specification (visible only on this page) === Message Move this DML statement out of the loop or process sObjects by batch. ''' == Comments And Links (visible only on this page) === on 5 Jul 2019, 17:35:38 Nicolas Harraudeau wrote: If the rule raise false positives one possible exception is: === Exceptions No issue will be raised when the DML statement is executed on a collection returned by a for loop. In this case the for loop already executed the DML statement in bulk. ---- public class myDMLLoop { public static void myFunction() { for (Task[] task: [Select Id, subject from Task]) { // Ok. The SOQL query is processing a batch of Tasks instead of a single one task.subject = task.subject + ' processed'; update task; // This update a batch of Tasks } for (List tasks: [Select Id, subject from Task]) { // Same here for (Task task: tasks) { task.subject = task.subject + ' processed'; } update tasks; } } } ---- endif::env-github,rspecator-view[]