DML Statements
DML Statements
===============
Salesforce provides a set of standard objects as part of the Salesforce CRM
application. And the Developer / Administrator can create their own objects based
on the requirement to store the application specific data.
To manage the records inside the objects, apex provides DML Statements.
By using DML statements, we can perform the operations on either One / More records
at a time.
By using DML statements, we can INSERT, UPDATE, DELETE, UNDELETE, UPSERT, MERGE the
records.
We can perform the DML operations on the records with the below 2 ways.
INSERT
UPDATE
DELETE
UNDELETE
UPSERT
MERGE
Database.Insert()
Database.Update()
Database.Delete()
Database.Undelete()
Database.Upsert()
Database.Merge()
Database.EmptyRecycleBin()
Governor Limits:
----------------
1. We can have max. of 150 DML statements inside a single Transaction.
When the user tries to use more than 150 DML statements inside a
transaction, salesforce will throws an exception "System.Limit Exception: Too many
DML statements:151".
Best Practices:
---------------
1. As a best practice, always avoid the usage of DML statements inside the
FOR Loop.
2. Always perform the DML operations on the records by using "Bulkification"
feature.
INSERT Statement:
=================
By using this statement, we can insert either one or multiple records into the
object at a time.
Syntax:
Insert Only One Record:
-----------------------
Insert <objectName>;
/*
Write an apex program, to insert 300 Hiring Manager Records into the object.
*/
Class Code:
-----------
public class DMLUtility
{
Public static void CreateBulkRecruiters()
{
// Create a Collection...
List<Hiring_Manager__C> lstHrs = new List<Hiring_Manager__c>();
if(counter != 1298)
{
hr.Email_ID__c = 'bulkhr'+counter+'@gmail.com';
}
hr.Contact_Number__c = '9900998877';
hr.Location__c = 'Chennai';
if(! lstHrs.isEmpty())
{
Insert lstHrs;
//Database.insert(lstHrs, false);
}
}
}
Execution:
----------
// Invoking the method..
DMLUtility.CreateBulkRecruiters();
Drawbacks:
----------
DML statements causes the below drawbacks upon performing the operations on the
multiple records.
1. DML Statements are purely Atomic. Which will use the implicit transactions
by default. So that, The Transaction will be RolledBack, if any of the operation
fails.
To avoid the above drawbacks, we have to use "Database" class methods to perform
the DML operations.
Database Class:
===============
Apex provides a standard class called as "Database", to be used to interact with
the Database objects, to perform all the DML operations inside the object.
Database.Insert()
Database.Update()
Database.Delete()
Database.UnDelete()
Database.Upsert()
Database.Merge()
Note:
1. Database Class methods will allows you to perform the "Partial
Processing". i.e. Upon performing the operations, if any of the record fails, then
it will continue with the rest of the records inside the collection.
3. We can track the error messages, which has been raised by the application,
upon failures. So that we can re-process the failed records.
Database.Insert():
------------------
By using this Method, we can insert a collection of records into the object
at a time.
Syntax:
Database.Insert(<CollectionName>, Boolean AllORNothing);
Note:
1. First Parameter indicates the collection of records to be get inserted.
Note:
We can store each record insertion result, by using "Database.SaveResult"
class.
Syntax:
Database.SaveResult[] <objectName> =
Database.Insert(<collection>, Boolean AllORNothing);
Database.SaveResult Class:
--------------------------
This class is used to store the result of a record upon insertion. To store the
multiple records insertion results, we need to create an Array / a Collection.
1. Boolean IsSuccess():
It returns TRUE, if the record is inserted successfully. Else it
returns FALSE.
2. GetID():
It returns the ID of the record, which has been generated by
salesforce, upon inserting the record successfully.
3. GetErrors():
This method is used to get the error messages, raised by the salesforce
upon operation failure.
Ex:
Database.Error[] errors = res.GetErrors();
Database.Error Class:
---------------------
This class is used to get the error messages raised by the salesforce upon
insertion failure.
1. GetMessage():
It returns the Error Message caused by Apex Runtime.
2. GetStatusCode():
It returns the Error Status Code.
Ex: REQUIRED_FIELD_MISSING, DUPLICATE_DETECTED, etc
3. GetFields():
It returns the Effected Fields inside the record failure.
/*
Write an apex program, to insert a collection of records, by allowing the
Partial Processing. And Track the Success / Failed record results.
*/
Class Code:
-----------
public class DMLUtility
{
Public static void CreateBulkRecruiters()
{
// Create a Collection...
List<Hiring_Manager__C> lstHrs = new List<Hiring_Manager__c>();
if(counter != 10298)
{
hr.Email_ID__c = 'bulkhr'+counter+'@gmail.com';
}
hr.Contact_Number__c = '9900998877';
hr.Location__c = 'Chennai';
if(! lstHrs.isEmpty())
{
Database.SaveResult[] results = Database.insert(lstHrs, false);
Execution:
----------
// Invoking the method..
DMLUtility.CreateBulkRecruiters();
Delete Statement:
=================
By using this statement, we can remove either one or more records from the object.
Syntax:
Remove Only One Record:
-----------------------
Delete <objectName>;
/*
Write an apex program, to Delete all the Contacts, whose last name starts
with the word "Contact".
*/
Class Code:
-----------
public class DMLUtility
{
Public static void DeleteContactsByLastName()
{
List<Contact> lstContacts = [Select id, lastname from Contact
Where lastname like 'Contact%'];
if(! lstContacts.isEmpty())
{
Database.DeleteResult[] results = Database.Delete(lstContacts, false);
}
// Delete [Select id, lastname from Contact Where lastname like 'Contact
%'];
}
}
Execution:
----------
// Invoking the method..
DMLUtility.DeleteContactsByLastName();
Assignments:
============
1. Write an apex program, to Delete Only those contacts, which are not
associated with any Account.
Note:
By using a single Delete statement, we can delete the records from the
multiple objects at a time.
Ex:
Id accId = '001......';
Id hrId = 'a01.......';
Id leadId = '00Q......';
lstIds.Add(accId);
lstIds.Add(hrId);
lstIds.Add(leadId);
if(! lstIds.isEmpty())
{
Database.Delete(lstIds,false);
}
UnDelete Statement:
===================
By using this statement, we can re-store the deleted records back to the actual
object. We can re-store all / specific records into the actual object, by adding
the required user defined conditions.
Syntax:
Re-Store Only One Record:
-------------------------
Undelete <objectName>;
/*
Write an apex program, to re-store the contacts back to the actual object,
whose first name is starting with the specified characters.
*/
Class Code:
-----------
public class DMLUtility
{
Public static void RestoreContactsByName(string startsWith)
{
if(startsWith != null && startsWith != '')
{
List<Contact> lstContacts = [Select id, firstname, lastname, isDeleted
from Contact
where isDeleted = true and
firstname =: startsWith
ALL ROWS ];
system.debug('Collection Size is....: '+ lstContacts.size());
if(! lstContacts.isEmpty())
{
Database.UndeleteResult[] results =
Database.undelete(lstContacts, false);
}
/*
Undelete [Select id, firstname, lastname, isDeleted
from Contact
where isDeleted = true and
firstname =: startsWith
ALL ROWS ];
*/
}
}
}
Execution:
----------
// Invoking the method..
DMLUtility.RestoreContactsByName('Bulk');
Update Statement:
=================
By using this statement, we can update either one or more or all records exist
inside the specified object with the required values.
Syntax:
Update Single Record:
---------------------
Update <objectName>;
Ex:
List<Account> lstAccounts = [Select id, name,
rating, industry, phone, fax
from Account
Where rating = 'Hot'];
Ex:
if(! lstAccounts.isEmpty())
{
for(Account acc : lstAccounts)
{
acc.Phone = '9988998899';
acc.fax = '9988554433';
acc.industry = 'Banking';
}
}
Step 3: Once the records has been assigned with the New
values, then Commit the changes back to the Database by using
Update Statement.
if(! lstAccounts.isEmpty())
{
Update lstAccounts;
}
/*
Write an apex program, To assign the Title as "Sales Head" for the Contacts,
whose first name is "Bulk".
*/
Class Code:
-----------
public class DMLUtility
{
Public static void UpdateContactsTitle()
{
// Get the required contacts...
List<Contact> lstContacts = [Select id, firstname, lastname, title
from Contact
Where firstname = 'Bulk'];
Execution:
----------
// Invoking the method..
DMLUtility.UpdateContactsTitle();
/*
Write an apex program, to De-Activate a User based on the user name supplied
at runtime.
*/
Class Code:
-----------
public class DMLUtility
{
Public static void DeActivateUser(string uName)
{
if(uName != null && uName != '')
{
User u = [Select id, isActive, username
from User
Where username =: uName and isActive = true];
if(u != null)
{
u.isActive = false;
update u;
}
}
}
}
Execution:
----------
// Invoking the method..
DMLUtility.DeActivateUser('[email protected]');
/*
Write an apex program, to transfer the ownership of All Hot Rating Accounts
to "Manager User".
*/
Class Code:
-----------
public class DMLUtility
{
Public static void TransferAccountsOwnership()
{
// Get the User to transfer the ownership..
User targetUser = [Select id, username, isActive
from User
Where username = '[email protected]' and isActive = true];
if(targetUser.Id != null)
{
// Get Hot Rating Accounts...
List<Account> lstAccounts = [Select id, name, rating, industry, ownerid
from Account
Where rating = 'Hot'];
if(! lstAccounts.isEmpty())
{
for(Account acc : lstAccounts)
{
acc.OwnerId = targetUser.Id;
}
Execution:
----------
// Invoking the method..
DMLUtility.TransferAccountsOwnership();
Assignments:
============
1. Write an apex program, to assign the Rating as "Hot" for all
Banking Accounts.
2. Write an apex program, to Remove all the Contacts associated with the Account
"Edge Communications".
3. Write an apex program, to transfer the Ownership of all the Lead Records
associated with "Hyderabad City" to "Hyderabad Sales Queue".
UpSert Statement:
=================
Upsert is a combination of both "Update + Insert".
Instead of using 2 DML statements to insert and update the records into the same
object. We can reduce the DML statements by using "Upsert Statement".
By using this Statement, we can Insert and Update the records into an object at a
time.
Syntax:
Upsert a Single Record:
-----------------------
Upsert <objectName>;
Note:
Upsert statement will insert the records, which are Not having the record id.
If the record contains the Id, then it will update the record into the
object.
/*
Write an apex program, To update the Location as "Hyderabad" for all the
Hiring Manager's Whose name starts with the word 'Apex'.
And insert a New Hiring Manager Record also into the object.
*/
Class Code:
-----------
public class DMLUtility
{
Public static void UpserHiringManagerRecords()
{
// Prepare the collection..
List<Hiring_Manager__C> hrsToUpsert = new List<Hiring_Manager__c>();
hrsToUpsert.Add(hr);
}
}
hrsToUpsert.Add(hr);
if(! hrsToUpsert.isEmpty())
{
Upsert hrsToUpsert;
}
}
}
Execution:
----------
// Invoking the method..
DMLUtility.UpserHiringManagerRecords();