# SOQL, SOSL and DML in Apex

*Platform Developer Study Guide · Process Automation and Logic · Last updated October 15, 2026 · https://www.certifyforce.com/study-guide/platform-developer/process-automation-and-logic/soql-sosl-and-dml-in-apex*

How to write inline SOQL (bind variables, relationship queries, aggregates, FOR UPDATE) and SOSL in Apex, predict exactly what each returns, and choose between DML statements and Database methods with partial success.

- Certification: Salesforce Platform Developer
- Exam section: Process Automation and Logic
- Study guide: https://www.certifyforce.com/study-guide/platform-developer

**Official exam objective:**

> Given a scenario, write SOSL, SOQL, and DML statements in Apex, and assess what they will return.

## What the exam expects

- Write inline SOQL with bind variables, including `IN :collection`, and predict whether it returns a list, one sObject, an Integer or AggregateResult rows.
- Choose dot notation (child to parent) or a subquery (parent to child) to fetch related records in one query.
- Choose SOSL over SOQL when a text term must be found across several objects, and read its list of lists.
- Choose between DML statements and Database methods, use `allOrNone = false` for partial success, and use upsert with an external ID.
- Lock rows with `FOR UPDATE` and know what that costs.

Key terms: **bind variable** (an Apex variable prefixed with a colon in a query), **relationship name** (the name SOQL uses to walk a lookup), **AggregateResult** (the row type of aggregate queries), **allOrNone** (the Database method flag for partial success), **external ID** (a field upsert can match on).

## Key facts

| Fact | Detail | Source |
|---|---|---|
| Query with no rows into a List | Returns an empty list, not null | [SOQL and SOSL Queries](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_SOQL.htm) |
| Query into a single sObject | Zero or several rows cause a runtime exception | [Using SOQL Queries That Return One Record](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_SOQL_single_row.htm) |
| Unaliased aggregate key | `expr0`, `expr1` ... in SELECT order | [Working with SOQL Aggregate Functions](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_SOQL_agg_fns.htm) |
| SOSL result | List of lists, one per RETURNING object, same order | [SOQL and SOSL Queries](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_SOQL.htm) |
| SOSL default result cap | Top 2,000 matches by relevancy | [Salesforce Object Search Language (SOSL)](https://developer.salesforce.com/docs/platform/salesforce-soql-sosl/guide/sforce-api-calls-sosl.html) |
| Query limits per transaction | 100 SOQL (200 async), 20 SOSL, 50,000 rows retrieved by SOQL | [Execution Governors and Limits](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_gov_limits.htm) |
| DML limits per transaction | 150 statements, 10,000 records processed | [Execution Governors and Limits](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_gov_limits.htm) |
| allOrNone default | true: one failure fails every record | [DML Statements vs. Database Class Methods](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_dml_database.htm) |
| Upsert keys | Id, external ID field, or idLookup standard field | [Upserting Records](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_dml_examples_upsert.htm) |
| FOR UPDATE lock wait | 10 seconds, then QueryException | [Locking Statements](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_locking_statements.htm) |

## Check yourself

- Why does code test a query result with `isEmpty()` instead of comparing it to null?
- When should a developer use SOSL instead of SOQL?
- Why can a bulk load keep its valid rows with `Database.insert(records, false)` but not with `insert records`?
- How do you read `SUM(Amount)` with no alias from an AggregateResult?

## Sources

- [SOQL and SOSL Queries](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_SOQL.htm)
- [Salesforce Object Query Language (SOQL)](https://developer.salesforce.com/docs/platform/salesforce-soql-sosl/guide/sforce-api-calls-soql.html)
- [Write SOQL Queries](https://trailhead.salesforce.com/content/learn/modules/apex_database/apex_database_soql)
- [Manipulate Records with DML](https://trailhead.salesforce.com/content/learn/modules/apex_database/apex_database_dml)
- [Using Apex Variables in SOQL and SOSL Queries](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_SOQL_variables.htm)
- [Understanding Relationship Names](https://developer.salesforce.com/docs/platform/salesforce-soql-sosl/guide/sforce-api-calls-soql-relationships-understanding.html)
- [Understanding Relationship Query Limitations](https://developer.salesforce.com/docs/platform/salesforce-soql-sosl/guide/sforce-api-calls-soql-relationships-query-limits.html)
- [Working with SOQL Aggregate Functions](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_SOQL_agg_fns.htm)
- [Aggregate Functions](https://developer.salesforce.com/docs/platform/salesforce-soql-sosl/guide/sforce-api-calls-soql-select-agg-functions.html)
- [Salesforce Object Search Language (SOSL)](https://developer.salesforce.com/docs/platform/salesforce-soql-sosl/guide/sforce-api-calls-sosl.html)
- [Using SOQL Queries That Return One Record](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_SOQL_single_row.htm)
- [DML Statements vs. Database Class Methods](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_dml_database.htm)
- [Upserting Records](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_dml_examples_upsert.htm)
- [Locking Statements](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/langCon_apex_locking_statements.htm)
- [Execution Governors and Limits](https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_gov_limits.htm)

## About the full unit

The "Core concepts", "Exam traps" and "Worked scenario" sections of this unit, its 9 linked practice questions, and unlimited timed mock exams are included with the Platform Developer pack (USD $19): https://www.certifyforce.com/practice-exams
