Apex – Batch Processing

Apex – Batch Processing ”; Previous Next In this chapter, we will understand Batch Processing in Apex. Consider a scenario wherein, we will process large number of records on daily basis, probably the cleaning of data or maybe deleting some unused data. What is Batch Apex? Batch Apex is asynchronous execution of Apex code, specially designed for processing the large number of records and has greater flexibility in governor limits than the synchronous code. When to use Batch Apex? When you want to process large number of records on daily basis or even on specific time of interval then you can go for Batch Apex. Also, when you want an operation to be asynchronous then you can implement the Batch Apex. Batch Apex is exposed as an interface that must be implemented by the developer. Batch jobs can be programmatically invoked at runtime using Apex. Batch Apex operates over small batches of records, covering your entire record set and breaking the processing down to manageable chunks of data. Using Batch Apex When we are using the Batch Apex, we must implement the Salesforce-provided interface Database.Batchable, and then invoke the class programmatically. You can monitor the class by following these steps − To monitor or stop the execution of the batch Apex Batch job, go to Setup → Monitoring → Apex Jobs or Jobs → Apex Jobs. Database.Batchable interface has the following three methods that need to be implemented − Start Execute Finish Let us now understand each method in detail. Start The Start method is one of the three methods of the Database.Batchable interface. Syntax global void execute(Database.BatchableContext BC, list<sobject<) {} This method will be called at the starting of the Batch Job and collects the data on which the Batch job will be operating. Consider the following points to understand the method − Use the Database.QueryLocator object when you are using a simple query to generate the scope of objects used in the batch job. In this case, the SOQL data row limit will be bypassed. Use the iterable object when you have complex criteria to process the records. Database.QueryLocator determines the scope of records which should be processed. Execute Let us now understand the Execute method of the Database.Batchable interface. Syntax global void execute(Database.BatchableContext BC, list<sobject<) {} where, list<sObject< is returned by the Database.QueryLocator method. This method gets called after the Start method and does all the processing required for Batch Job. Finish We will now discuss the Finish method of the Database.Batchable interface. Syntax global void finish(Database.BatchableContext BC) {} This method gets called at the end and you can do some finishing activities like sending an email with information about the batch job records processed and status. Batch Apex Example Let us consider an example of our existing Chemical Company and assume that we have requirement to update the Customer Status and Customer Description field of Customer Records which have been marked as Active and which have created Date as today. This should be done on daily basis and an email should be sent to a User about the status of the Batch Processing. Update the Customer Status as ”Processed” and Customer Description as ”Updated Via Batch Job”. // Batch Job for Processing the Records global class CustomerProessingBatch implements Database.Batchable<sobject> { global String [] email = new String[] {”[email protected]”}; // Add here your email address here // Start Method global Database.Querylocator start (Database.BatchableContext BC) { return Database.getQueryLocator(”Select id, Name, APEX_Customer_Status__c, APEX_Customer_Decscription__c From APEX_Customer__c WHERE createdDate = today AND APEX_Active__c = true”); // Query which will be determine the scope of Records fetching the same } // Execute method global void execute (Database.BatchableContext BC, List<sobject> scope) { List<apex_customer__c> customerList = new List<apex_customer__c>(); List<apex_customer__c> updtaedCustomerList = new List<apex_customer__c>(); // List to hold updated customer for (sObject objScope: scope) { APEX_Customer__c newObjScope = (APEX_Customer__c)objScope ; // type casting from generic sOject to APEX_Customer__c newObjScope.APEX_Customer_Decscription__c = ”Updated Via Batch Job”; newObjScope.APEX_Customer_Status__c = ”Processed”; updtaedCustomerList.add(newObjScope); // Add records to the List System.debug(”Value of UpdatedCustomerList ”+updtaedCustomerList); } if (updtaedCustomerList != null && updtaedCustomerList.size()>0) { // Check if List is empty or not Database.update(updtaedCustomerList); System.debug(”List Size ” + updtaedCustomerList.size()); // Update the Records } } // Finish Method global void finish(Database.BatchableContext BC) { Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage(); // Below code will fetch the job Id AsyncApexJob a = [Select a.TotalJobItems, a.Status, a.NumberOfErrors, a.JobType, a.JobItemsProcessed, a.ExtendedStatus, a.CreatedById, a.CompletedDate From AsyncApexJob a WHERE id = :BC.getJobId()]; // get the job Id System.debug(”$$$ Jobid is”+BC.getJobId()); // below code will send an email to User about the status mail.setToAddresses(email); mail.setReplyTo(”[email protected]”); // Add here your email address mail.setSenderDisplayName(”Apex Batch Processing Module”); mail.setSubject(”Batch Processing ”+a.Status); mail.setPlainTextBody(”The Batch Apex job processed” + a.TotalJobItems+”batches with ”+a.NumberOfErrors+”failures”+”Job Item processed are”+a.JobItemsProcessed); Messaging.sendEmail(new Messaging.Singleemailmessage [] {mail}); } } To execute this code, first save it and then paste the following code in Execute anonymous. This will create the object of class and Database.execute method will execute the Batch job. Once the job is completed then an email will be sent to the specified email address. Make sure that you have a customer record which has Active as checked. // Paste in Developer Console CustomerProessingBatch objClass = new CustomerProessingBatch(); Database.executeBatch (objClass); Once this class is executed, then check the email address you have provided where you will receive the email with information. Also, you can check the status of the batch job via the Monitoring page and steps as provided above. If you check the debug logs, then you can find the List size which indicates how many records have been processed. Limitations We can only have 5 batch job processing at a time. This is one of the limitations of Batch Apex. Scheduling the Apex Batch Job using Apex Detail Page You can schedule the Apex class via Apex detail page as given below − Step 1 − Go to Setup ⇒ Apex Classes, Click on Apex Classes. Step 2 − Click on the Schedule Apex button. Step 3 − Provide details. Scheduling the Apex Batch Job using Schedulable Interface

Apex – Quick Guide

Apex – Quick Guide ”; Previous Next Apex – Overview What is Apex? Apex is a proprietary language developed by the Salesforce.com. As per the official definition, Apex is a strongly typed, object-oriented programming language that allows developers to execute the flow and transaction control statements on the Force.com platform server in conjunction with calls to the Force.com API. It has a Java-like syntax and acts like database stored procedures. It enables the developers to add business logic to most system events, including button clicks, related record updates, and Visualforce pages.Apex code can be initiated by Web service requests and from triggers on objects. Apex is included in Performance Edition, Unlimited Edition, Enterprise Edition, and Developer Edition. Features of Apex as a Language Let us now discuss the features of Apex as a Language − Integrated Apex has built in support for DML operations like INSERT, UPDATE, DELETE and also DML Exception handling. It has support for inline SOQL and SOSL query handling which returns the set of sObject records. We will study the sObject, SOQL, SOSL in detail in future chapters. Java like syntax and easy to use Apex is easy to use as it uses the syntax like Java. For example, variable declaration, loop syntax and conditional statements. Strongly Integrated With Data Apex is data focused and designed to execute multiple queries and DML statements together. It issues multiple transaction statements on Database. Strongly Typed Apex is a strongly typed language. It uses direct reference to schema objects like sObject and any invalid reference quickly fails if it is deleted or if is of wrong data type. Multitenant Environment Apex runs in a multitenant environment. Consequently, the Apex runtime engine is designed to guard closely against runaway code, preventing it from monopolizing shared resources. Any code that violates limits fails with easy-to-understand error messages. Upgrades Automatically Apex is upgraded as part of Salesforce releases. We don”t have to upgrade it manually. Easy Testing Apex provides built-in support for unit test creation and execution, including test results that indicate how much code is covered, and which parts of your code can be more efficient. When Should Developer Choose Apex? Apex should be used when we are not able to implement the complex business functionality using the pre-built and existing out of the box functionalities. Below are the cases where we need to use apex over Salesforce configuration. Apex Applications We can use Apex when we want to − Create Web services with integrating other systems. Create email services for email blast or email setup. Perform complex validation over multiple objects at the same time and also custom validation implementation. Create complex business processes that are not supported by existing workflow functionality or flows. Create custom transactional logic (logic that occurs over the entire transaction, not just with a single record or object) like using the Database methods for updating the records. Perform some logic when a record is modified or modify the related object”s record when there is some event which has caused the trigger to fire. Working Structure of Apex As shown in the diagram below (Reference: Salesforce Developer Documentation), Apex runs entirely on demand Force.com Platform Flow of Actions There are two sequence of actions when the developer saves the code and when an end user performs some action which invokes the Apex code as shown below − Developer Action When a developer writes and saves Apex code to the platform, the platform application server first compiles the code into a set of instructions that can be understood by the Apex runtime interpreter, and then saves those instructions as metadata. End User Action When an end-user triggers the execution of Apex, by clicking a button or accessing a Visualforce page, the platform application server retrieves the compiled instructions from the metadata and sends them through the runtime interpreter before returning the result. The end-user observes no differences in execution time as compared to the standard application platform request. Since Apex is the proprietary language of Salesforce.com, it does not support some features which a general programming language does. Following are a few features which Apex does not support − It cannot show the elements in User Interface. You cannot change the standard SFDC provided functionality and also it is not possible to prevent the standard functionality execution. Creating multiple threads is also not possible as we can do it in other languages. Understanding the Apex Syntax Apex code typically contains many things that we might be familiar with from other programming languages. Variable Declaration As strongly typed language, you must declare every variable with data type in Apex. As seen in the code below (screenshot below), lstAcc is declared with data type as List of Accounts. SOQL Query This will be used to fetch the data from Salesforce database. The query shown in screenshot below is fetching data from Account object. Loop Statement This loop statement is used for iterating over a list or iterating over a piece of code for a specified number of times. In the code shown in the screenshot below, iteration will be same as the number of records we have. Flow Control Statement The If statement is used for flow control in this code. Based on certain condition, it is decided whether to go for execution or to stop the execution of the particular piece of code. For example, in the code shown below, it is checking whether the list is empty or it contains records. DML Statement Performs the records insert, update, upsert, delete operation on the records in database. For example, the code given below helps in updating Accounts with new field value. Following is an example of how an Apex code snippet will look like. We are going to study all these Apex programming concepts further in this tutorial. Apex – Environment In this chapter, we will understand the environment for our Salesforce Apex development. It is assumed that you already have a Salesforce edition

Apex – Trigger Design Patterns

Apex – Trigger Design Patterns ”; Previous Next Design patterns are used to make our code more efficient and to avoid hitting the governor limits. Often developers can write inefficient code that can cause repeated instantiation of objects. This can result in inefficient, poorly performing code, and potentially the breaching of governor limits. This most commonly occurs in triggers, as they can operate against a set of records. We will see some important design pattern strategies in this chapter. Bulk Triggers Design Patterns In real business case, it will be possible that you may need to process thousands of records in one go. If your trigger is not designed to handle such situations, then it may fail while processing the records. There are some best practices which you need to follow while implementing the triggers. All triggers are bulk triggers by default, and can process multiple records at a time. You should always plan to process more than one record at a time. Consider a business case, wherein, you need to process large number of records and you have written the trigger as given below. This is the same example which we had taken for inserting the invoice record when the Customer Status changes from Inactive to Active. // Bad Trigger Example trigger Customer_After_Insert on APEX_Customer__c (after update) { for (APEX_Customer__c objCustomer: Trigger.new) { if (objCustomer.APEX_Customer_Status__c == ”Active” && trigger.oldMap.get(objCustomer.id).APEX_Customer_Status__c == ”Inactive”) { // condition to check the old value and new value APEX_Invoice__c objInvoice = new APEX_Invoice__c(); objInvoice.APEX_Status__c = ”Pending”; insert objInvoice; //DML to insert the Invoice List in SFDC } } } You can now see that the DML Statement has been written in for the loop block which will work when processing only few records but when you are processing some hundreds of records, it will reach the DML Statement limit per transaction which is the governor limit. We will have a detailed look on Governor Limits in a subsequent chapter. To avoid this, we have to make the trigger efficient for processing multiple records at a time. The following example will help you understand the same − // Modified Trigger Code-Bulk Trigger trigger Customer_After_Insert on APEX_Customer__c (after update) { List<apex_invoice__c> InvoiceList = new List<apex_invoice__c>(); for (APEX_Customer__c objCustomer: Trigger.new) { if (objCustomer.APEX_Customer_Status__c == ”Active” && trigger.oldMap.get(objCustomer.id).APEX_Customer_Status__c == ”Inactive”) { //condition to check the old value and new value APEX_Invoice__c objInvoice = new APEX_Invoice__c(); objInvoice.APEX_Status__c = ”Pending”; InvoiceList.add(objInvoice);//Adding records to List } } insert InvoiceList; // DML to insert the Invoice List in SFDC, this list contains the all records // which need to be modified and will fire only one DML } This trigger will only fire 1 DML statement as it will be operating over a List and the List has all the records which need to be modified. By this way, you can avoid the DML statement governor limits. Trigger Helper Class Writing the whole code in trigger is also not a good practice. Hence you should call the Apex class and delegate the processing from Trigger to Apex class as shown below. Trigger Helper class is the class which does all the processing for trigger. Let us consider our invoice record creation example again. // Below is the Trigger without Helper class trigger Customer_After_Insert on APEX_Customer__c (after update) { List<apex_invoice__c> InvoiceList = new List<apex_invoice__c>(); for (APEX_Customer__c objCustomer: Trigger.new) { if (objCustomer.APEX_Customer_Status__c == ”Active” && trigger.oldMap.get(objCustomer.id).APEX_Customer_Status__c == ”Inactive”) { // condition to check the old value and new value APEX_Invoice__c objInvoice = new APEX_Invoice__c(); objInvoice.APEX_Status__c = ”Pending”; InvoiceList.add(objInvoice); } } insert InvoiceList; // DML to insert the Invoice List in SFDC } // Below is the trigger with helper class // Trigger with Helper Class trigger Customer_After_Insert on APEX_Customer__c (after update) { CustomerTriggerHelper.createInvoiceRecords(Trigger.new, trigger.oldMap); // Trigger calls the helper class and does not have any code in Trigger } Helper Class public class CustomerTriggerHelper { public static void createInvoiceRecords (List<apex_customer__c> customerList, Map<id, apex_customer__c> oldMapCustomer) { List<apex_invoice__c> InvoiceList = new Listvapex_invoice__c>(); for (APEX_Customer__c objCustomer: customerList) { if (objCustomer.APEX_Customer_Status__c == ”Active” && oldMapCustomer.get(objCustomer.id).APEX_Customer_Status__c == ”Inactive”) { // condition to check the old value and new value APEX_Invoice__c objInvoice = new APEX_Invoice__c(); // objInvoice.APEX_Status__c = ”Pending”; InvoiceList.add(objInvoice); } } insert InvoiceList; // DML to insert the Invoice List in SFDC } } In this, all the processing has been delegated to the helper class and when we need a new functionality we can simply add the code to the helper class without modifying the trigger. Single Trigger on Each sObject Always create a single trigger on each object. Multiple triggers on the same object can cause the conflict and errors if it reaches the governor limits. You can use the context variable to call the different methods from helper class as per the requirement. Consider our previous example. Suppose that our createInvoice method should be called only when the record is updated and on multiple events. Then we can control the execution as below − // Trigger with Context variable for controlling the calling flow trigger Customer_After_Insert on APEX_Customer__c (after update, after insert) { if (trigger.isAfter && trigger.isUpdate) { // This condition will check for trigger events using isAfter and isUpdate // context variable CustomerTriggerHelper.createInvoiceRecords(Trigger.new); // Trigger calls the helper class and does not have any code in Trigger // and this will be called only when trigger ids after update } } // Helper Class public class CustomerTriggerHelper { //Method To Create Invoice Records public static void createInvoiceRecords (List<apex_customer__c> customerList) { for (APEX_Customer__c objCustomer: customerList) { if (objCustomer.APEX_Customer_Status__c == ”Active” && trigger.oldMap.get(objCustomer.id).APEX_Customer_Status__c == ”Inactive”) { // condition to check the old value and new value APEX_Invoice__c objInvoice = new APEX_Invoice__c(); objInvoice.APEX_Status__c = ”Pending”; InvoiceList.add(objInvoice); } } insert InvoiceList; // DML to insert the Invoice List in SFDC } } Print Page Previous Next Advertisements ”;

Apex – Discussion

Discuss Apex ”; Previous Next Apex is a proprietary language developed by Salesforce.com. It is a strongly typed, object oriented programming language that allows developers to execute flow and transaction control statements on the Force.com platform server in conjunction with calls to the Force.com API. Print Page Previous Next Advertisements ”;

Apex – Triggers

Apex – Triggers ”; Previous Next Apex triggers are like stored procedures which execute when a particular event occurs. A trigger executes before and after an event occurs on record. Syntax trigger triggerName on ObjectName (trigger_events) { Trigger_code_block } Executing the Trigger Following are the events on which we can fir the trigger − insert update delete merge upsert undelete Trigger Example 1 Suppose we received a business requirement that we need to create an Invoice Record when Customer”s ”Customer Status” field changes to Active from Inactive. For this, we will create a trigger on APEX_Customer__c object by following these steps − Step 1 − Go to sObject Step 2 − Click on Customer Step 3 − Click on ”New” button in the Trigger related list and add the trigger code as give below. // Trigger Code trigger Customer_After_Insert on APEX_Customer__c (after update) { List InvoiceList = new List(); for (APEX_Customer__c objCustomer: Trigger.new) { if (objCustomer.APEX_Customer_Status__c == ”Active”) { APEX_Invoice__c objInvoice = new APEX_Invoice__c(); objInvoice.APEX_Status__c = ”Pending”; InvoiceList.add(objInvoice); } } // DML to insert the Invoice List in SFDC insert InvoiceList; } Explanation Trigger.new − This is the context variable which stores the records currently in the trigger context, either being inserted or updated. In this case, this variable has Customer object”s records which have been updated. There are other context variables which are available in the context – trigger.old, trigger.newMap, trigger.OldMap. Trigger Example 2 The above trigger will execute when there is an update operation on the Customer records. Suppose, the invoice record needs to be inserted only when the Customer Status changes from Inactive to Active and not every time; for this, we can use another context variable trigger.oldMap which will store the key as record id and the value as old record values. // Modified Trigger Code trigger Customer_After_Insert on APEX_Customer__c (after update) { List<apex_invoice__c> InvoiceList = new List<apex_invoice__c>(); for (APEX_Customer__c objCustomer: Trigger.new) { // condition to check the old value and new value if (objCustomer.APEX_Customer_Status__c == ”Active” && trigger.oldMap.get(objCustomer.id).APEX_Customer_Status__c == ”Inactive”) { APEX_Invoice__c objInvoice = new APEX_Invoice__c(); objInvoice.APEX_Status__c = ”Pending”; InvoiceList.add(objInvoice); } } // DML to insert the Invoice List in SFDC insert InvoiceList; } Explanation We have used the Trigger.oldMap variable which as explained earlier, is a context variable which stores the Id and old value of records which are being updated. Print Page Previous Next Advertisements ”;

Apex – Debugging

Apex – Debugging ”; Previous Next Debugging is an important part in any programming development. In Apex, we have certain tools that can be used for debugging. One of them is the system.debug() method which prints the value and output of variable in the debug logs. We can use the following two tools for debugging − Developer Console Debug Logs Debugging via Developer Console You can use the Developer console and execute anonymous functionality for debugging the Apex as below − Example Consider our existing example of fetching the customer records which have been created today. We just want to know if the query is returning the results or not and if yes, then we will check the value of List. Paste the code given below in execute anonymous window and follow the steps which we have done for opening execute anonymous window. Step 1 − Open the Developer console Step 2 − Open the Execute anonymous from ”Debug” as shown below. Step 3 − Open the Execute Anonymous window and paste the following code and click on execute. // Debugging The Apex List<apex_customer__c> customerList = new List<apex_customer__c>(); customerList = [SELECT Id, Name FROM APEX_Customer__c WHERE CreatedDate = today]; // Our Query System.debug(”Records on List are ”+customerList+” And Records are ”+customerList); // Debug statement to check the value of List and Size Step 4 − Open the Logs as shown below. Step 5 − Enter ”USER” in filter condition as shown below. Step 6 − Open the USER DEBUG Statement as shown below. Debugging via Debug Logs You can debug the same class via debug logs as well. Suppose, you have a trigger in Customer object and it needs to be debugged for some variable values, then you can do this via the debug logs as shown below − This is the Trigger Code which updates the Description field if the modified customer is active and you want to check the values of variables and records currently in scope − trigger CustomerTrigger on APEX_Customer__c (before update) { List<apex_customer__c> customerList = new List<apex_customer__c>(); for (APEX_Customer__c objCust: Trigger.new) { System.debug(”objCust current value is”+objCust); if (objCust.APEX_Active__c == true) { objCust.APEX_Customer_Description__c = ”updated”; System.debug(”The record which has satisfied the condition ”+objCust); } } } Follow the steps given below to generate the Debug logs. Step 1 − Set the Debug logs for your user. Go to Setup and type ”Debug Log” in search setup window and then click on Link. Step 2 − Set the debug logs as following. Step 3 − Enter the name of User which requires setup. Enter your name here. Step 4 − Modify the customer records as event should occur to generate the debug log. Step 5 − Now go to the debug logs section again. Open the debug logs and click on Reset. Step 6 − Click on the view link of the first debug log. Step 7 − Search for the string ”USER” by using the browser search as shown below. The debug statement will show the value of the field at which we have set the point. Print Page Previous Next Advertisements ”;

Apex – Security

Apex – Security ”; Previous Next Apex security refers to the process of applying security settings and enforcing the sharing rules on running code. Apex classes have security setting that can be controlled via two keywords. Data Security and Sharing Rules Apex generally runs in system context, that is, the current user”s permissions. Field-level security, and sharing rules are not taken into account during code execution. Only the anonymous block code executes with the permission of the user who is executing the code. Our Apex code should not expose the sensitive data to User which is hidden via security and sharing settings. Hence, Apex security and enforcing the sharing rule is most important. With Sharing Keyword If you use this keyword, then the Apex code will enforce the Sharing settings of current user to Apex code. This does not enforce the Profile permission, only the data level sharing settings. Let us consider an example wherein, our User has access to 5 records, but the total number of records is 10. So when the Apex class will be declared with the “With Sharing” Keyword, it will return only 5 records on which the user has access to. Example First, make sure that you have created at least 10 records in the Customer object with ”Name” of 5 records as ”ABC Customer” and rest 5 records as ”XYZ Customer”. Then, create a sharing rule which will share the ”ABC Customer” with all Users. We also need to make sure that we have set the OWD of Customer object as Private. Paste the code given below to Anonymous block in the Developer Console. // Class With Sharing public with sharing class MyClassWithSharing { // Query To fetch 10 records List<apex_customer__c> CustomerList = [SELECT id, Name FROM APEX_Customer__c LIMIT 10]; public Integer executeQuery () { System.debug(”List will have only 5 records and the actual records are” + CustomerList.size()+” as user has access to”+CustomerList); Integer ListSize = CustomerList.size(); return ListSize; } } // Save the above class and then execute as below // Execute class using the object of class MyClassWithSharing obj = new MyClassWithSharing(); Integer ListSize = obj.executeQuery(); Without Sharing Keyword As the name suggests, class declared with this keyword executes in System mode, i.e., irrespective of the User”s access to the record, query will fetch all the records. // Class Without Sharing public without sharing class MyClassWithoutSharing { List<apex_customer__c> CustomerList = [SELECT id, Name FROM APEX_Customer__c LIMIT 10]; // Query To fetch 10 records, this will return all the records public Integer executeQuery () { System.debug(”List will have only 5 records and the actula records are” + CustomerList.size()+” as user has access to”+CustomerList); Integer ListSize = CustomerList.size(); return ListSize; } } // Output will be 10 records. Setting Security for Apex Class You can enable or disable an Apex class for particular profile. The steps for the same are given below. You can determine which profile should have access to which class. Setting Apex class security from the class list page Step 1 − From Setup, click Develop → Apex Classes. Step 2 − Click the name of the class that you want to restrict. We have clicked on CustomerOperationClass. Step 3 − Click on Security. Step 4 − Select the profiles that you want to enable from the Available Profiles list and click Add, or select the profiles that you want to disable from the Enabled Profiles list and click on Remove. Step 5 − Click on Save. Setting Apex Security from Permission Set Step 1 − From Setup, click Manage Users → Permission Sets. Step 2 − Select a permission set. Step 3 − Click on Apex Class Access. Step 4 − Click on Edit. Step 5 − Select the Apex classes that you want to enable from the Available Apex Classes list and click Add, or select the Apex classes that you want to disable from the Enabled Apex Classes list and click remove. Step 6 − Click the Save button. Print Page Previous Next Advertisements ”;

Apex – SOQL

Apex – SOQL ”; Previous Next This is Salesforce Object Query Language designed to work with SFDC Database. It can search a record on a given criterion only in single sObject. Like SOSL, it cannot search across multiple objects but it does support nested queries. SOQL Example Consider our ongoing example of Chemical Company. Suppose, we need a list of records which are created today and whose customer name is not ”test”. In this case, we will have to use the SOQL query as given below − // fetching the Records via SOQL List<apex_invoice__c> InvoiceList = new List<apex_invoice__c>(); InvoiceList = [SELECT Id, Name, APEX_Customer__r.Name, APEX_Status__c FROM APEX_Invoice__c WHERE createdDate = today AND APEX_Customer__r.Name != ”Test”]; // SOQL query for given criteria // Printing the fetched records System.debug(”We have total ”+InvoiceList.size()+” Records in List”); for (APEX_Invoice__c objInvoice: InvoiceList) { System.debug(”Record Value is ”+objInvoice); // Printing the Record fetched } You can run the SOQL query via the Query Editor in the Developer console as shown below. Run the query given below in the Developer Console. Search for the Invoice records created today. SELECT Id, Name, APEX_Customer__r.Name, APEX_Status__c FROM APEX_Invoice__c WHERE createdDate = today You must select the fields for which you need the values, otherwise, it can throw run time errors. Traversing Relationship Fields This is one of the most important parts in SFDC as many times we need to traverse through the parent child object relationship Also, there may be cases when you need to insert two associated objects records in Database. For example, Invoice object has relationship with the Customer object and hence one Customer can have many invoices. Suppose, you are creating the invoice and then you need to relate this invoice to Customer. You can use the following code for this functionality − // Now create the invoice record and relate it with the Customer object // Before executing this, please create a Customer Records with Name ”Customer // Creation Test” APEX_Invoice__c objInvoice = new APEX_Invoice__c(); // Relating Invoice to customer via id field of Customer object objInvoice.APEX_Customer__c = [SELECT id FROM APEX_Customer__c WHERE Name = ”Customer Creation Test” LIMIT 1].id; objInvoice.APEX_Status__c = ”Pending”; insert objInvoice; //Creating Invoice System.debug(”Newly Created Invoice”+objInvoice); //Newly created invoice Execute this code snippet in the Developer Console. Once executed, copy the Id of invoice from the Developer console and then open the same in SFDC as shown below. You can see that the Parent record has already been assigned to Invoice record as shown below. Fetching Child Records Let us now consider an example wherein, all the invoices related to particular customer record need to be in one place. For this, you must know the child relationship name. To see the child relationship name, go to the field detail page on the child object and check the “Child Relationship” value. In our example, it is invoices appended by __r at the end. Example In this example, we will need to set up data, create a customer with name as ”ABC Customer” record and then add 3 invoices to that customer. Now, we will fetch the invoices the Customer ”ABC Customer” has. Following is the query for the same − // Fetching Child Records using SOQL List<apex_customer__c> ListCustomers = [SELECT Name, Id, (SELECT id, Name FROM Invoices__r) FROM APEX_Customer__c WHERE Name = ”ABC Customer”]; // Query for fetching the Child records along with Parent System.debug(”ListCustomers ”+ListCustomers); // Parent Record List<apex_invoice__c> ListOfInvoices = ListCustomers[0].Invoices__r; // By this notation, you could fetch the child records and save it in List System.debug(”ListOfInvoices values of Child ”+ListOfInvoices); // Child records You can see the Record values in the Debug logs. Fetching Parent Record Suppose, you need to fetch the Customer Name of Invoice the creation date of which is today, then you can use the query given below for the same − Example Fetch the Parent record”s value along with the child object. // Fetching Parent Record Field value using SOQL List<apex_invoice__c> ListOfInvoicesWithCustomerName = new List<apex_invoice__c>(); ListOfInvoicesWithCustomerName = [SELECT Name, id, APEX_Customer__r.Name FROM APEX_Invoice__c LIMIT 10]; // Fetching the Parent record”s values for (APEX_Invoice__c objInv: ListOfInvoicesWithCustomerName) { System.debug(”Invoice Customer Name is ”+objInv.APEX_Customer__r.Name); // Will print the values, all the Customer Records will be printed } Here we have used the notation APEX_Customer__r.Name, where APEX_Customer__r is parent relationship name, here you have to append the __r at the end of the Parent field and then you can fetch the parent field value. Aggregate Functions SOQL does have aggregate function as we have in SQL. Aggregate functions allow us to roll up and summarize the data. Let us now understand the function in detail. Suppose, you wanted to know that what is the average revenue we are getting from Customer ”ABC Customer”, then you can use this function to take up the average. Example // Getting Average of all the invoices for a Perticular Customer AggregateResult[] groupedResults = [SELECT AVG(APEX_Amount_Paid__c)averageAmount FROM APEX_Invoice__c WHERE APEX_Customer__r.Name = ”ABC Customer”]; Object avgPaidAmount = groupedResults[0].get(”averageAmount”); System.debug(”Total Average Amount Received From Customer ABC is ”+avgPaidAmount); Check the output in Debug logs. Note that any query that includes an aggregate function returns its results in an array of AggregateResult objects. AggregateResult is a readonly sObject and is only used for query results. It is useful when we need to generate the Report on Large data. There are other aggregate functions as well which you can be used to perform data summary. MIN() − This can be used to find the minimum value MAX() − This can be used to find the maximum value. Binding Apex Variables You can use the Apex variable in SOQL query to fetch the desired results. Apex variables can be referenced by the Colon (:) notation. Example // Apex Variable Reference String CustomerName = ”ABC Customer”; List<apex_customer__c> ListCustomer = [SELECT Id, Name FROM APEX_Customer__c WHERE Name = :CustomerName]; // Query Using Apex variable System.debug(”ListCustomer Name”+ListCustomer); // Customer Name Print Page Previous Next

Apex – Database Methods

Apex – Database Methods ”; Previous Next Database class methods is another way of working with DML statements which are more flexible than DML Statements like insert, update, etc. Differences between Database Methods and DML Statements DML Statements Database Methods Partial Update is not allowed. For example, if you have 20 records in list, then either all the records will be updated or none. Partial update is allowed. You can specify the Parameter in Database method as true or false, true to allow the partial update and false for not allowing the same. You cannot get the list of success and failed records. You can get the list of success and failed records as we have seen in the example. Example − insert listName Example − Database.insert(listName, False), where false indicate that partial update is not allowed. Insert Operation Inserting new records via database methods is also quite simple and flexible. Let us consider the previous scenario wherein, we have inserted new records using the DML statements. We will be inserting the same using Database methods. Example // Insert Operation Using Database methods // Insert Customer Records First using simple DML Statement. This Customer Record will be // used when we will create Invoice Records APEX_Customer__c objCust = new APEX_Customer__C(); objCust.Name = ”Test”; insert objCust; // Inserting the Customer Records // Insert Operation Using Database methods APEX_Invoice__c objNewInvoice = new APEX_Invoice__c(); List<apex_invoice__c> InvoiceListToInsert = new List<apex_invoice__c>(); objNewInvoice.APEX_Status__c = ”Pending”; objNewInvoice.APEX_Customer__c = objCust.id; objNewInvoice.APEX_Amount_Paid__c = 1000; InvoiceListToInsert.add(objNewInvoice); Database.SaveResult[] srList = Database.insert(InvoiceListToInsert, false); // Database method to insert the records in List // Iterate through each returned result by the method for (Database.SaveResult sr : srList) { if (sr.isSuccess()) { // This condition will be executed for successful records and will fetch the ids // of successful records System.debug(”Successfully inserted Invoice. Invoice ID: ” + sr.getId()); // Get the invoice id of inserted Account } else { // This condition will be executed for failed records for(Database.Error objErr : sr.getErrors()) { System.debug(”The following error has occurred.”); // Printing error message in Debug log System.debug(objErr.getStatusCode() + ”: ” + objErr.getMessage()); System.debug(”Invoice oject field which are affected by the error:” + objErr.getFields()); } } } Update Operation Let us now consider our business case example using the database methods. Suppose we need to update the status field of Invoice object but at the same time, we also require information like status of records, failed record ids, success count, etc. This is not possible by using DML Statements, hence we must use Database methods to get the status of our operation. Example We will be updating the Invoice”s ”Status” field if it is in status ”Pending” and date of creation is today. The code given below will help in updating the Invoice records using the Database.update method. Also, create an Invoice record before executing this code. // Code to update the records using the Database methods List<apex_invoice__c> invoiceList = [SELECT id, Name, APEX_Status__c, createdDate FROM APEX_Invoice__c WHERE createdDate = today]; // fetch the invoice created today List<apex_invoice__c> updatedInvoiceList = new List<apex_invoice__c>(); for (APEX_Invoice__c objInvoice: invoiceList) { if (objInvoice.APEX_Status__c == ”Pending”) { objInvoice.APEX_Status__c = ”Paid”; updatedInvoiceList.add(objInvoice); //Adding records to the list } } Database.SaveResult[] srList = Database.update(updatedInvoiceList, false); // Database method to update the records in List // Iterate through each returned result by the method for (Database.SaveResult sr : srList) { if (sr.isSuccess()) { // This condition will be executed for successful records and will fetch // the ids of successful records System.debug(”Successfully updated Invoice. Invoice ID is : ” + sr.getId()); } else { // This condition will be executed for failed records for(Database.Error objErr : sr.getErrors()) { System.debug(”The following error has occurred.”); // Printing error message in Debug log System.debug(objErr.getStatusCode() + ”: ” + objErr.getMessage()); System.debug(”Invoice oject field which are affected by the error:” + objErr.getFields()); } } } We will be looking at only the Insert and Update operations in this tutorial. The other operations are quite similar to these operations and what we did in the last chapter. Print Page Previous Next Advertisements ”;

Apex – Example

Apex – Example ”; Previous Next Enterprise Application Development Example For our tutorial, we will be implementing the CRM application for a Chemical Equipment and Processing Company. This company deals with suppliers and provides services. We will work out small code snippets related to this example throughout our tutorial to understand every concept in detail. For executing the code in this tutorial, you will need to have two objects created: Customer and Invoice objects. If you already know how to create these objects in Salesforce, you can skip the steps given below. Else, you can follow the step by step guide below. Creating Customer Object We will be setting up the Customer object first. Step 1 − Go to Setup and then search for ”Object” as shown below. Then click on the Objects link as shown below. Step 2 − Once the object page is opened, then click on the ”Create New Object” button as shown below. Step 3 − After clicking on button, the new object creation page will appear and then enter all the object details as entered below. Object name should be Customer. You just have to enter the information in the field as shown in the screenshot below and keep other default things as it is. Enter the information and then click on the ”Save” button − By following the above steps, we have successfully created the Customer object. Creating the Custom Fields for Customer object Now that we have our Customer object set up, we will create a field ”Active” and then you can create the other fields by following similar steps. The Name and API name of the field will be given in the screenshot. Step 1 − We will be creating a field named as ”Active” of data type as Checkbox. Go to Setup and click on it. Step 2 − Search for ”Object” as shown below and click on it. Step 3 − Click on object ”Customer”. Step 4 − Once you have clicked on the Customer object link and the object detail page appears, click on the New button. Step 5 − Now, select the data type as Checkbox and click Next. Step 6 − Enter the field name and label as shown below. Step 7 − Click on Visible and then click Next. Step 8 − Now click on ”Save”. By following the above steps, our custom field ”Active” is created. You have to follow all the above custom field creation steps for the remaining fields. This is the final view of customer object once all the fields are created − Creating Invoice Object Step 1 − Go to Setup and search for ”Object” and then click on the Objects link as shown below. Step 2 − Once the object page is opened, then click on the ”Create New Object” button as shown below. Step 3 − After clicking on the button, the new object creation page will appear as shown in the screenshot below. You need to enter the details here. The object name should be Invoice. This is similar to how we created the Customer object earlier in this tutorial. Step 4 − Enter the information as shown below and then click on the ”Save” button. By following these steps, your Invoice object will be created. Creating the Custom Fields for Invoice object We will be creating the field Description on Invoice object as shown below − Step 1 − Go to Setup and click on it. Step 2 − Search for ”Object” as shown below and click on it. Step 3 − Click on object ”Invoice”. And then click on ”New”. Step 4 − Select the data type as Text Area and then click on Next button. Step 5 − Enter the information as given below. Step 6 − Click on Visible and then Next. Step 7 − Click on Save. Similarly, you can create the other fields on the Invoice object. By this, we have created the objects that are needed for this tutorial. We will be learning various examples in the subsequent chapters based on these objects. Print Page Previous Next Advertisements ”;