Navigating through parent-child relationships in SOQL refers to the ability to traverse and query data across related objects in Salesforce using SOQL. Parent-child relationships exist when one object is related to another object, such as a master-detail or lookup relationship. For example, if you have a parent object called “Account” and a child object called “Contact,” you can use a SOQL query to retrieve information from both objects. However, the number of child records levels that can be returned in a single SOQL query from one parent object is one. Here’s an example:
SELECT Id, Name, (SELECT Id, FirstName, LastName FROM Contacts) FROM Account
In this query, we are retrieving the Account’s Id and Name fields, as well as the related Contacts’ Id, FirstName, and LastName fields. The (SELECT FROM Contacts) part of the query is known as a subquery and allows you to retrieve data from the child object.
The data types that can be returned from any SOQL request include the following:
•\ Single sObject: An SOQL query can return a single sObject record. This is useful when you want to retrieve and work with a specific record or object, typically used with LIMIT 1 in the query.
•\ List of sObjects: An SOQL query can return a list of sObjects. This is useful when you want to retrieve multiple records or objects that meet certain criteria.
•\ Integer: This is typically returned when using aggregate functions like COUNT(). It’s useful for getting a count of records that meet certain criteria.
•\ AggregateResult: An SOQL query can return an AggregateResult object by using aggregate functions like COUNT, SUM, MAX, MIN, AVG with a GROUP BY or without. These functions group and summarize data, potentially reducing the number of rows in the result set. For example, if you use GROUP BY on a field, the query may return fewer rows because it groups similar values together.
Dynamic SOQL refers to the ability to construct and execute SOQL queries dynamically at runtime, rather than having the query hardcoded in your Apex code. Dynamic SOQL allows you to construct queries based on runtime conditions or user inputs. You can dynamically adjust various parts of your query, including the fields to select, the object to query, and the conditions in the WHERE clause. This provides flexibility when you need to create queries with variable criteria or when the object and field names are not known until runtime. It can be executed using the Database.query() method.
Here is an example of a simple dynamic Salesforce SOQL query you can test in
Anonymous Window:
To to Setup ➤ Developer Console Debug ➤ Open Execute Anonymous Window, put the code block and press on Execute button.
String objectName = ‘Account’;
String fieldName = ‘Name’;
String fieldValue = ‘Myname’; // Replace with the desired account name
String queryString = ‘SELECT Id, ‘ + fieldName + ‘ FROM ‘ + objectName + ‘ WHERE ‘ + fieldName + ‘ LIKE \’%’ + fieldValue + ‘%\”; List<sObject> sList = Database.query(queryString);
for (sObject s : sList) {
System.debug(s);
}
But the construction of dynamic SOQL queries, as shown in the preceding example, can potentially introduce security vulnerabilities if the input values such as fieldValue are not properly sanitized or validated. Constructing queries by concatenating strings without proper handling can lead to SQL injection vulnerabilities.
You can use the String.escapeSingleQuotes method to properly escape single quotes in dynamic SOQL queries in Salesforce. Here’s how you can modify your example:
String objectName = ‘Account’;
String fieldName = ‘Name’;
String fieldValue = ‘Myname’;
String queryString = ‘SELECT Id, ‘ + fieldName + ‘ FROM ‘ + objectName + ‘ WHERE ‘ + fieldName +
for (sObject s : sList) {
System.debug(s);
}
In this modification, String.escapeSingleQuotes is applied to the fieldValue variable to ensure that any single quotes within the value are properly escaped. The escaped value is then used in the dynamic SOQL query.
While using String.escapeSingleQuotes adds an extra layer of protection, it’s important to note that using bind variables in your static SOQL queries is generally a better practice for preventing injection vulnerabilities. If possible, consider using bind variables in your queries, as Salesforce automatically handles the necessary escaping when using them. Here’s how you can modify your example to use bind variables:
String objectName = ‘Account’;
String fieldName = ‘Name’;
String fieldValue = ‘Myname’;
[SELECT Id, Name FROM Account WHERE Name = :fieldValue];
for (Account acc : accountList) {
System.debug(acc);
}
In this modified example, :fieldValue is a bind variable. It is used in the SOQL query, and Salesforce will automatically handle the proper escaping and processing of the variable, reducing the risk of injection attacks.