Salesforce Apex Trigger | Part 1
Salesforce Apex Trigger Basics
So I am dividing this apex trigger into 3 levels i.e. Basic Level, Implementation Level and Advance Level so that It will help you to understand from very basics to advance.
So let's get started with all fundamentals.
Before insert event will occur before new records are inserted into the database. So we can not retrieve the new records using DML operations in before trigger i.e. when we have a customer table with following records.
| CID | Name | Age | Phone |
----------------------------------
| 111 | aaa | 23 | 1234 |
| 222 | bbb | 34 | 3455 |
| 333 | ccc | 45 | 9876 |
----------------------------------
When we are trying to perform insert these two new records
| 444 | ddd | 43 | 1234 |
| 555 | eee | 23 | 3456 |
----------------------------------
If there is any before insert triggers and we can have written any DML in it like below.
trigger myExample on customer__c (before insert)
{
List<customer__c> cmr = [SELECT cid__c, Name, Age__c, Phone__c FROM customer__c]
//This query will only fetch three records as remaining two records are not yet inserted
}
=============================================
Triggers :
Triggers are an Apex code that executes before or after the following types of DML operations :
- Insert
- Update
- Delete
- Merge
- Upsert
- Undelete
2. After Triggers
Before triggers can be used to update or validate values of a record before they are saved to the database.
After triggers can be used to access field values of the records that are stored in the database and use these values to make changes in other records.
=============================================
trigger triggerName on objectName (trigger_events)
{
// your code here
}
=============================================
Where trigger_events can be a comma-separated list of events.
NOTE :
Trigger.New is a context variable which contains a list of records which has caused the triggers to fire.
As this context variable, we are using in our example I have explained here. There are a few more which we will discuss in the next episodes.
Trigger.New can be used in the following trigger events :
Now let's understand how it works
- Insert
- Update
- Delete
- Merge
- Upsert
- Undelete
Triggers are divided into 2 types :
1. Before Triggers2. After Triggers
Before triggers can be used to update or validate values of a record before they are saved to the database.
After triggers can be used to access field values of the records that are stored in the database and use these values to make changes in other records.
=============================================
trigger triggerName on objectName (trigger_events)
{
// your code here
}
=============================================
Types of events in the triggers :
1. Before Insert
2. Before Update
3. Before Delete
4. After Insert
5. After Update
6. After Delete
7. After Undelete
For Example :
=============================================
trigger myExample on Account (before insert, after delete)
{
// Your Code Here
}
}
NOTE :
- Triggers can only contain keywords applicable to an inner class.
- You do not have to commit the data manually, it automatically saves into the database.
Trigger.New :
As this context variable, we are using in our example I have explained here. There are a few more which we will discuss in the next episodes.
Trigger.New can be used in the following trigger events :
1. Before Insert
2. Before Update
3. After Insert
4. After Update
5. After Undelete
2. Before Update
3. After Insert
4. After Update
5. After Undelete
First, create a table Customer
Now we will see how to use Trigger.New in before insert :
| CID | Name | Age | Phone |
----------------------------------
| 111 | aaa | 23 | 1234 |
| 222 | bbb | 34 | 3455 |
| 333 | ccc | 45 | 9876 |
----------------------------------
In this object, if we are trying to insert new records into customer object
----------------------------------
| 111 | aaa | 23 | 1234 |
| 222 | bbb | 34 | 3455 |
| 333 | ccc | 45 | 9876 |
----------------------------------
----------------------------------
| 111 | aaa | 23 | 1234 |
| 222 | bbb | 34 | 3455 |
| 333 | ccc | 45 | 9876 |
----------------------------------
In this object, if we are trying to insert new records into customer object
----------------------------------
| 444 | ddd | 43 | 1234 |
| 555 | eee | 23 | 3456 |
----------------------------------
Then the new records which we are trying to insert are stored in Trigger.new in before insert event.
Then the new records which we are trying to insert are stored in Trigger.new in before insert event.
Which means
List<Customer__c> cmr = Trigger.New
List<Customer__c> cmr = Trigger.New
----------------------------------
| 444 | ddd | 43 | 1234 |
| 555 | eee | 23 | 3456 |
----------------------------------
These records are stored into Trigger.New
| 444 | ddd | 43 | 1234 |
| 555 | eee | 23 | 3456 |
----------------------------------
These records are stored into Trigger.New
For Example :
=============================================
for(customer__c : Trigger.New)
{
c.Age__c = 23;
}
=============================================Before insert event will occur before new records are inserted into the database. So we can not retrieve the new records using DML operations in before trigger i.e. when we have a customer table with following records.
| CID | Name | Age | Phone |
----------------------------------
| 111 | aaa | 23 | 1234 |
| 222 | bbb | 34 | 3455 |
| 333 | ccc | 45 | 9876 |
----------------------------------
When we are trying to perform insert these two new records
| 444 | ddd | 43 | 1234 |
| 555 | eee | 23 | 3456 |
----------------------------------
If there is any before insert triggers and we can have written any DML in it like below.
trigger myExample on customer__c (before insert)
{
List<customer__c> cmr = [SELECT cid__c, Name, Age__c, Phone__c FROM customer__c]
//This query will only fetch three records as remaining two records are not yet inserted
}
=============================================
Before Insert :
These triggers will fire when we are trying to insert a new record into a specified object.
Operations which we have written in the trigger will be implemented before new records are saved to the database.
In before Insert, Trigger.New stores the list of new records which we are trying to insert.
Let's have a look at scenario based triggers
When we are trying to insert new record into object. If there is any record existing with same account name it should prevent duplicate record.
=============================================
trigger accountInsert on Account (before insert)
{
for(Account acc : Trgger.New)
{
List<Account> mynew = [SELECT Id, Name FROM Account WHERE Name =: acc.Name];
if(mynew.size() > 0)
{
acc.Name.addError('Account with same name is existing');
}
}
}
=============================================
Scenario 2 :
Write a trigger to prefix Account Name with 'Mr.' when a new record is inserted.
=============================================
Scenario 2 :
Write a trigger to prefix Account Name with 'Mr.' when a new record is inserted.
=============================================
trigger accountprefix on Account(before insert)
{
for(Account a : Trigger.New)
{
a.Name = 'Mr'+a.Name;
}
}
=============================================
Scenario 3 :
Whenever a new record is created into an account object. Before this new record is inserted into Account, delete all the contacts records with this account name.
=============================================
trigger contactDeletion on Account(before insert)
{
List<string> mynames = new List<string>();
for(Account a : Trigger.New)
{
mynames.add(a.Name);
}
List<contact> mycontacts = [SELECT Id, Name FROM Contact WHERE Name In: mynames];
delete mycontacts;
}
{
for(Account a : Trigger.New)
{
a.Name = 'Mr'+a.Name;
}
}
=============================================
Scenario 3 :
Whenever a new record is created into an account object. Before this new record is inserted into Account, delete all the contacts records with this account name.
=============================================
trigger contactDeletion on Account(before insert)
{
List<string> mynames = new List<string>();
for(Account a : Trigger.New)
{
mynames.add(a.Name);
}
List<contact> mycontacts = [SELECT Id, Name FROM Contact WHERE Name In: mynames];
delete mycontacts;
}
=============================================
I hope these scenarios are clear to you.
When we insert new records
After triggers will be performed after committing the new records into a database which means.
After sorting these records then after insert trigger will be called, So operation written in the trigger will be performed after records are successfully inserted.
Whenever a new Contact is created for an account update the corresponding account phone with the new Contact phone field.
=============================================
trigger updatephone on contact(after insert)
{
List<Account> acc = new List<Account>();
for(Contact c : Trigger.New)
{
Account a = [SELECT Id, Phone, FROM Account WHERE Id =: c.AccountId];
a.phone = c.phone;
acc.add(a);
}
update acc;
}
=============================================
These are some example scenarios where we can use these triggers.
This is how we can use before, after triggers In this EPISODE.
AFTER INSERT :
This triggers will be fired after new records are successfully saved to the database.
We can use Trigger.New to refer to the list of new records which are have inserted.
We can use Trigger.New to refer to the list of new records which are have inserted.
On Trigger.New we can only perform read-only operations.
On the new list of records, we can perform DML operations.
On the new list of records, we can perform DML operations.
If we want to perform any changes on those records we have performed DML operations.
Example :
| CID | Name | Age | Phone |
----------------------------------
| 111 | aaa | 23 | 1234 |
| 222 | bbb | 34 | 3455 |
| 333 | ccc | 45 | 9876 |
----------------------------------
----------------------------------
| 444 | ddd | 43 | 1234 |
| 555 | eee | 23 | 3456 |
----------------------------------
----------------------------------
| 111 | aaa | 23 | 1234 |
| 222 | bbb | 34 | 3455 |
| 333 | ccc | 45 | 9876 |
| 444 | ddd | 43 | 1234 |
| 555 | eee | 23 | 3456 |
| 444 | ddd | 43 | 1234 |
| 555 | eee | 23 | 3456 |
----------------------------------
Whenever a new Contact is created for an account update the corresponding account phone with the new Contact phone field.
=============================================
trigger updatephone on contact(after insert)
{
List<Account> acc = new List<Account>();
for(Contact c : Trigger.New)
{
Account a = [SELECT Id, Phone, FROM Account WHERE Id =: c.AccountId];
a.phone = c.phone;
acc.add(a);
}
update acc;
}
=============================================
This is how we can use before, after triggers In this EPISODE.
In the next episodes, we will discuss about DML operations, context variables, Recursive triggers, calling apex class in triggers etc. with a scenario so stay tuned...
WOHOOO !! YOU HAVE JUST COMPLETED SALESFORCE APEX TRIGGER PART 1 EPISODE
WOHOOO !! YOU HAVE JUST COMPLETED SALESFORCE APEX TRIGGER PART 1 EPISODE
If you like this salesforcekid learning platform please let me know in the Comment section...Also, Share with your salesforce folks wish you
Happy learning ☁️⚡️ (Learn. Help. Share.)
Salesforce Apex Trigger | Part 1
Reviewed by
on
Rating:
Hi , SOQL inside forloop is a good practice?
ReplyDeletetrigger updatephone on contact(after insert)
{
List acc = new List();
for(Contact c : Trigger.New)
{
Account a = [SELECT Id, Phone, FROM Account WHERE Id =: c.AccountId];
a.phone = c.phone;
acc.add(a);
}
update acc;
}
No, SOQL inside for loop is not best practice.
DeleteAny reason for doing soql Account a = [SELECT Id, Phone, FROM Account WHERE Id =: c.AccountId]; inside the loop in your example?
DeleteAs this episode is to understand the syntex and how to write it I have not mentioned about following best practices. In the upcoming Episodes I am going to mention examples with best practices as well.
DeleteThanks ��
Trigger UpdatePhone on Contact(before insert)
Delete{
setaccId=new set();
for(contact con:trigger.new)
{
accId.add(con.AccountId);
}
MapaccMap=new Map([select id,phone from Account where id IN:accId]);
for(contact con:trigger.new)
{
if(accMap.containsKey(con.accountId))
{
con.mobilePhone=accMap.get(con.AccountId).phone;
}
}
}
Thats great learning, very good platform to learn basics
ReplyDeleteCan you please tell ne why below code not triggering when i am inserting duplicate account name.
ReplyDeletepublic class Basic {
public static void mymethod(){
List ACC = NEW List ();
for(Account B : ACC){
List rep = [Select id,Name from Account where Name =:B.Name];
if(rep.size()>0)
{
B.Name.addError('Name is already exisit');
}
}
}
}
-------------------------------------
trigger Verify on Account (before insert) {
if(trigger.isinsert && trigger.isbefore){
Basic.mymethod();
}
}
correct one is :)
Deletepublic class Basic {
public static void mymethod(lIST ACC){
for(Account B : ACC){
List rep = [Select id,Name from Account where Name =:B.Name];
if(rep.size()>0)
{
B.Name.addError('Name is already exisit');
}
}
}
}
---------------------------
public class Basic {
public static void mymethod(lIST ACC){
for(Account B : ACC){
List rep = [Select id,Name from Account where Name =:B.Name];
if(rep.size()>0)
{
B.Name.addError('Name is already exisit');
}
}
}
}
How to write this apex?
ReplyDelete