I actually have a Swiss Army Knife Batch Processing class that I use for occasions like this. I use it in orgs where there's a lot of "traffic" going on, and I need to quickly update a large number of records, but I don't want to query the data, update spreadsheets, and put the data back. This code allows me to do this:
Database.executeBatch(
new ExecAnonBatch(
Generators.fromQuery('select id from Contact'),
Executors.updateField(Contact.Mass_Update_Checkbox__c, true)));
Basically, anyone with Author Apex code can perform a mass update on all records in the system with a simple script. Note that I called it a Swiss Army Knife; the complete class also includes creating records, deleting records, undeleting records, sending emails, and a few other tricks I like to have available on hand. This is part of what will be available in my open-source library when it's ready.
Here's the relevant portions (n.b. I'm typing this from scratch, there may be a few typos):
public class ExecAnonBatch implements Database.Batchable<Object> {
public interface generator {
Object generate();
}
public interface executor {
void execute(Object[] values);
}
generator gen;
executor exec;
public ExecAnonBatch(generator theGenerator, executor theExecutor) {
gen = theGenerator;
exec = theExecutor;
}
public Iterable<Object> start(Database.BatchableContext context) {
return (Iterable<Object>) gen.generate();
}
public void execute(Database.BatchableContext context, Object[] scope) {
exec.execute(scope);
}
public void finish(Database.BatchableContext context) {
}
}
public class Generators {
class QueryGenerator implements ExecAnonBatch.generator {
String queryString;
QueryGenerator(String query) {
queryString = query;
}
public Object generate() {
return Database.getQueryLocator(queryString);
}
}
public static ExecAnonBatch.generator fromQuery(String query) {
return new QueryGenerator(query);
}
}
public class Executors {
class FieldUpdate implements ExecAnonBatch.executor {
SObjectField field;
Object value;
FieldUpdate(SObjectField updateField, Object fieldValue) {
field = updateField;
value = fieldValue;
}
public void execute(Object[] scope) {
SObject[] records = (SObject[])scope;
for(SObject record: records) {
record.put(field, value);
}
Database.update(records, false);
}
}
public static ExecAnonBatch.executor updateField(SObjectField field, Object value) {
return new FieldUpdate(field, value);
}
}
Now with unit tests, too:
@isTest class ExecAnonBatchTest {
@isTest static void test() {
Test.startTest();
Database.executeBatch(
new ExecAnonBatch(
Generators.fromQuery('select id from user limit 1'),
Executors.updateField(User.LastName, 'Doe')));
Test.stopTest();
System.assertEquals('Doe', [SELECT LastName FROM User ORDER BY LastModifiedDate DESC LIMIT 1].LastName);
}
}
Install this package: Production/Developer/Trial | Sandbox