1

Within Apex, is there a way to build up a static SOQL query using query "parts" or "fragments"?

Consider the following silly example:

public with sharing class MyController {
  @AuraEnabled(cacheable=true)
  public static List<Asset> getAssets(Boolean shouldSortDescending) {
    SomeType query = [SELECT Name from Asset];

    // Can we append to the query based on some conditions? 
    if (shouldSortDescending) { 
      query.push([ORDER BY Name DESC]);
    } else {
      query.push([ORDER BY Name ASC]);
    }

    return query;
  }
}

The best I can find is to drop down to Dynamic SOQL, build up the query using a String and then call Database.query() or Database.queryWithBinds().

One use-case for conditionally building up a static query would be to factor out some complex logic in the query into a helper function that could just return the relevant fragment.

(e.x.: This Apex class might have several methods that return Assets. In each case, we want to return the same fields. So the SELECT ... From Asset is identical in each case and it would be nice to just return that from a single function.)

2
  • 1
    What you describe is exactly what dynamic SOQL is all about. Static SOQL is, by definition, static.
    – Phil W
    Feb 27, 2023 at 20:40
  • 1
    +1 to Derek's answer. And take care to use simple bind expressions or escaping to avoid SOQL injection in dynamic SOQL.
    – Keith C
    Feb 27, 2023 at 20:55

1 Answer 1

3

No, there is not a way to append parts to a static query.

The use case that you describe is what dynamic SOQL was made to do.

In practice, I think that the main difference between static and dynamic SOQL is that you get compile-time checks on SObject and field references (it'll complain at compile time instead of at run-time if you misspell an object or field name, mess up the child relationship name, etc...). This can be convenient at times, and inconvenient at other times (e.g. when you want to use unpackaged metadata in an unlocked 2GP because your package depends on an artifact that's owned by a different package).

The conclusion here is that you should just use dynamic SOQL for what you want to do here.

5
  • When using dynamic SOQL, can Salesforce still resolve Object and field dependencies for an Apex class or is that support now lost?
    – kennyc
    Feb 27, 2023 at 21:48
  • @kennyc I'm not entirely sure what you mean here. Are you talking about something like pulling in dependencies for changesets? Or perhaps the "where is this used" button that appears in some places? If so, then the answer is no in both of those cases.
    – Derek F
    Feb 27, 2023 at 22:48
  • If I go Setup - Apex Classes - [Class] - Show Dependencies, it will list the Objects and Fields this class depends on. I'm assuming that's because a static SOQL query exposes that dependency. Because a dynamic query is really just a string, I was a worried I'd lose this dependency tracking. We might be undertaking a lot of refactoring in the near future, so having Salesforce know about dependencies would be a huge help.
    – kennyc
    Feb 27, 2023 at 23:05
  • @kennyc that 'dependencies' you are talking about are part of DDL in a conventional database and what you are querying is DML. In other words, they are not the same at all. And yes, anything you can query statically you can also query dynamically including functions, aggregates, and relationships.
    – zaitsman
    Feb 28, 2023 at 0:22
  • I'll need to verify this, but if a static SOQL query (in an Apex class) references a custom object, and I try to delete that custom object from my org, I was under the impression Salesforce would warn me that the custom object has dependencies and is thus "in-use". The dependency checker must know this because the objects and fields it lists on that Setup page, match exactly the objects and fields in my Apex class' static query. Presumably I would lose that dependency checking if I switch to the string-based, dynamic queries. At least that's what I thought...
    – kennyc
    Feb 28, 2023 at 1:39

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .