You can actually include variable references in Dynamic SOQL strings, you just need to ensure there is a variable of that name and correct type in scope when your query is executed for example...
public with sharing class DynamicSOQLDemo {
public static String buildQuery()
{
return 'select Id, Name from Account where Id in :accountIds';
}
public static void executeQuery()
{
Id accountId = '001G000000qdART';
Set<Id> accountIds = new Set<Id> { accountId };
List<Account> accounts = Database.query(buildQuery());
System.assertEquals(accountIds.size(), accounts.size());
}
}
You obviously need to take a little care with this, as the risk is even greater for runtime issues if the bind variable names change either in the query or in the code ultimately making the Database.query call.
As per the reference in the formal docs also...
You can use simple bind variables in dynamic SOQL query strings. The following is allowed:
String myTestString = 'TestName';
List<sObject> L = Database.query('SELECT Id FROM MyCustomObject__c WHERE Name = :myTestString');
However, unlike inline SOQL, dynamic SOQL can’t use bind variable fields in the query string. The following example isn’t supported and results in a Variable does not exist error:
MyCustomObject__c myVariable = new MyCustomObject__c(field1__c ='TestField');
List<sObject> L = Database.query('SELECT Id FROM MyCustomObject__c WHERE field1__c = :myVariable.field1__c');
Further Update: Following a bit more clarification on the ask here. As regards making this even more dynamic, while the doc snippet above doesn't go into much further detail (e.g. Apex dereferences). I did just try, sorry no joy with this approach... even tried a property get/set....
public with sharing class DynamicSOQLDemo {
public static String buildQuery()
{
return 'select Id, Name from Account where Id in :params.ids';
}
public static void executeQuery()
{
Id accountId = '001G000000qdART';
Set<Id> accountIds = new Set<Id> { accountId };
QueryParams params = new QueryParams();
params.ids = accountIds;
List<Account> accounts = Database.query(buildQuery());
System.assertEquals(accountIds.size(), accounts.size());
}
public class QueryParams
{
public Set<Id> ids {get; set;}
}
}
System.QueryException: Variable does not exist: params.ids
P.S. I assume you probably would rule out making a outbound Apex REST Execute Anonymous callout.... #wherethereisawillthereisaway ;-)