SOQL Queries in Apex

Salesforce developers rely heavily on SOQL queries in Apex to interact with database. Whether you are a complete newbie or seasoned coder, mastering SOQL is crucial for building efficient and scalable applications.

Syntax of SOQL query in Apex

nameOfSObject variableName = [SOQL_Query];
/*OR*/
List<nameOfSObject> variableName = [SOQL_QUERY];
/*OR*/
Map<Id, nameOfSObject> variableName = new Map<Id, nameOfSObject>([SOQL_QUERY]);

Though, salesforce does not restrict you to use a sObject variable to collect returned records from SOQL but, it is advisable to use collection variables or collection of sObject variables to store returned records from SOQL.

Retrieve field values from SOQL query in Apex

Use dot (.) operator to retrieve field values.

Syntax

variableName.fieldName

Example

List<Opportunity> oppList = [SELECT Id, Name, StageName 
                             FROM Opportunity];
//Access the first element of oppList 
System.debug('1st element '+oppList[0].Name+' '+oppList[0].StageName);
//for loop to iterate over all values present in oppList and print Name as well as Stage
for(Opportunity opp : oppList){
    System.debug('Name: '+opp.Name+' '+'Stage: '+opp.StageName);
}

Binding Variables in SOQL

You can use Apex variables in SOQL using a colon (:). These variables are called bind variables. You can use binding variable after WHERE clause and in LIMIT and OFFSET clause.

String Stage = 'Closed Won';
//Query all opportunities with closed won stage.
List<Opportunity> oppList = [SELECT Id, Name, Amount 
                             FROM Opportunity
                             WHERE StageName =: Stage];
System.debug('oppList size '+oppList.size());
for(Opportunity opp : oppList){
    System.debug('Name '+opp.Name+' '+'Amount '+opp.Amount);
}

Handling Aggregate Queries in Apex

AggregateResult object is used to store the results of aggregate queries. AggregateResult is a read-only object. Please checkout SOQL functions to learn about aggregate queries.

The get() method uses alias, fieldname or expri when no alias is provided. i in expri represents order of aggregated fields without alias.

Syntax

List<AggregateResult> variableName = [Aggregate_SOQL_query];
variableName[0].get('fieldName/alias/expri');

Example

String Stage = 'Closed Won';
List<AggregateResult> agrList = [SELECT MIN(Amount) minAmount, MAX(Amount) 
                                 FROM Opportunity
                                 WHERE StageName =: Stage];
System.debug('agrList size '+agrList.size());
for(AggregateResult agr : agrList){
    System.debug(agr.get('minAmount')+' '+agr.get('expr0'));
}

SOQL For Loop

SOQL for loop can process one record at a time using single sObject, or in chunk of 200 using sObject list. It uses efficient chunking with call to query or querymore methods of SOAP API. It is used to limit heap size.

Syntax

for(sObjectName variableName : [SOQL_Query]){
    //logic here
}
/*OR*/
for(List<sObjectName> variableName : [SOQL_Query]){
   //logic here
}

sObject list format is optimal choice if you must use DML statement within for loop because, this format executes code within for loop once for 200 sObject records

Example of SOQL for loop

String Stage = 'Closed Won';
for(Opportunity opp : [SELECT Id, Name 
                       FROM Opportunity 
                       WHERE StageName =: Stage]){
                           System.debug('Opp>>> '+Opp);
                       }
System.debug('CPU time in milliseconds >>> '+Limits.getCpuTime());
System.debug('heap size in bytes>>> '+Limits.getHeapSize());

Output

Example of List Assignment for loop

String Stage = 'Closed Won';
List<Opportunity> oppList = [SELECT Id, Name 
                       	     FROM Opportunity 
                       	     WHERE StageName =: Stage];
for(Opportunity opp : oppList){
   System.debug('Opp>>> '+Opp);
}
System.debug('CPU time in milliseconds >>> '+Limits.getCpuTime());
System.debug('heap size in bytes>>> '+Limits.getHeapSize());

Output

Between SOQL for loop and List Assignment for loop which one should we choose? after going through the output of both approaches, we can conclude that SOQL for loop is suitable when heap size is priority and List assignment for loop keep CPU cycles on priority.

Best practices for using SOQL in Apex

Use Collection Variables to store results of SOQL query

This approach will help you to avoid following exceptions List has no rows for assignment to sObject and List has more than one row for assignment to sObject exception. This exception occurs when you use single sObject variable to store result of SOQL query.

Avoid SOQL queries inside Loops

Writing SOQL inside loop will exhaust governor limit of 100 SOQL queries in a transcation.

Use Selective Filters

Use Indexed fields such as Id , Name , CreatedDate etc in WHERE clause of SOQL query. This will help us to improve performance and avoid unexpected runtime exceptions.

Query only required fields

It reduces the amount of data retrieved, which improves efficiency and avoid heap limit exceptions.

Use SOQL for Loops for large data volumes

It will process query results in batches under the hood, reducing memory usage and avoiding heap exceptions.

Whether you’re writing simple queries or complex logics, mastering SOQL queries in apex is essential for salesforce development. Follow best practices, handle exceptions gracefully, and optimize performance using SOQL for loops.

You may also like...

Leave a Reply

Your email address will not be published. Required fields are marked *