Mastering DML Operations in Apex: A Practical Guide for Salesforce Developers
When working with Salesforce’s Apex programming language, managing data is central to nearly every application. This is where DML (Data Manipulation Language) operations come into play. Apex provides a powerful and flexible way to perform DML operations such as inserting, updating, deleting, and undeleting records.
In this post, we’ll walk through various DML operations in Apex, explore best practices, and highlight potential pitfalls to avoid.
What is DML in Apex?
DML statements in Apex are used to manipulate records in the Salesforce database. You can perform actions like:
- insert – Add new records
- update – Modify existing records
- upsert – Insert or update records depending on whether they exist
- delete – Remove records
- undelete – Restore deleted records
- merge – Combine duplicate records (only for Account, Contact, Lead)
Examples of DML Operations
- Insert Operation
You can create and insert records in one go:
Account acc = new Account(Name = ‘Test Account’);
insert acc;
Or insert multiple records:
List<Account> accList = new List<Account>{
new Account(Name = ‘Account 1’),
new Account(Name = ‘Account 2’)
};
insert accList;
Use Case: A company collects leads through a web form and stores them in Salesforce.
Lead newLead = new Lead(
FirstName = ‘John’,
LastName = ‘Doe’,
Company = ‘Acme Corp’,
Email = ‘john.doe@acme.com’,
Status = ‘New’
);
insert newLead;
- Update Operation
Update records by changing field values and using the update keyword:
acc.Name = ‘Updated Account’;
update acc;
Use Case: After a successful client meeting, all opportunities in “Negotiation” stage are moved to “Closed Won”.
List<Opportunity> opps = [SELECT Id, StageName FROM Opportunity WHERE StageName = ‘Negotiation’];
for (Opportunity opp : opps) {
opp.StageName = ‘Closed Won’;
}
update opps;
- Upsert Operation
Upsert is used when you’re unsure whether to insert or update:
upsert acc;
If you’re using a custom field to identify uniqueness:
upsert acc External_Id__c;
Use Case: Syncing contact data from an external database where contacts may already exist based on External_Id__c.
Contact contact = new Contact(
FirstName = ‘Jane’,
LastName = ‘Smith’,
Email = ‘jane.smith@example.com’,
External_Id__c = ‘EXT12345’
);
upsert contact External_Id__c;
- Delete Operation
To delete records:
delete acc;
Or a list of records:
delete accList;
Use Case: A marketing team wants to delete all campaigns marked as “Obsolete”.
List<Campaign> obsoleteCampaigns = [SELECT Id FROM Campaign WHERE Status = ‘Obsolete’];
delete obsoleteCampaigns;
- Undelete Operation
To restore deleted records (if within the 15-day recycle bin retention window):
undelete acc;
Use Case: Restore contacts deleted in the past week, where LastName starts with “Temp”.
undelete [SELECT Id FROM Contact WHERE IsDeleted = true AND LastName LIKE ‘Temp%’ ALL ROWS];
- Merge Operation
To merge duplicate records
merge masterRecord duplicateRecord;
Or merge multiple:
merge masterRecord duplicate1 duplicate2;
Use Case: Two duplicate accounts need to be merged to consolidate related data.
Account master = [SELECT Id, Name FROM Account WHERE Name = ‘Acme Corp Ltd’ LIMIT 1];
Account duplicate = [SELECT Id, Name FROM Account WHERE Name = ‘Acme Corp Limited’ LIMIT 1];
merge master duplicate;
Note: Only Account, Contact, and Lead objects support merge.
DML and Exception Handling
Always wrap DML in try-catch blocks to handle errors gracefully:
try {
insert acc;
} catch (DmlException e) {
System.debug(‘DML Exception: ‘ + e.getMessage());
}
DML Statements vs. Database Class
You can also use the Database class for more control:
Database.SaveResult result = Database.insert(acc, false); // false = don’t throw error
if (!result.isSuccess()) {
System.debug(‘Error: ‘ + result.getErrors()[0].getMessage());
}
Use the allOrNone flag wisely—setting it to false allows partial success in bulk operations.
Governor Limits and Best Practices
- Salesforce enforces a limit of 150 DML statements per Apex transaction.
- Batch your DML: Use lists to handle bulk operations rather than executing individual statements.
- Use Database.insert() in bulk scenarios to avoid full transaction rollback.
- Follow bulkification best practices to ensure your code scales well.
Final Thoughts
Mastering DML operations is essential for every Apex developer. With careful exception handling and adherence to governor limits, you can build efficient and robust data management logic in your Salesforce applications.