QueryException when using Invocable Method and SOQL

apexdynamic-soqlinvocable-methodsoqlvisual-workflow

We have a flow that presents a multi-picklist on a screen that presents related Accounts.
We then want to create a related object on each of those selected Accounts.

To allow for modularity, we want to use the same code for any object in the future. A multi-picklist requires us to split the string by ';'

When I debug the flow it errors out on the apex action with:

Error Occurred: An Apex error occurred: System.QueryException: expecting a right parentheses, found 'h00000h1C59AAE'

I'm confident it is due to the SOQL query composition and the 'IN' clause from the QueyException, but not sure what is throwing the syntax error.

public class FlowController {
        
    @InvocableMethod( label='Show Outputs' description='Getting multiple values' )
    public static List<List<SObject>> showOutputs(List<Requests> inputs) {
        
        Requests objInput = inputs.get(0);
        System.debug('start flow');
          String tempStr = inputs[0].values;
          System.debug('start split');
          List<String> idValues = tempStr.split(';');

        String queryString = 'SELECT Id, Name FROM ' + objInput.objectType + ' WHERE Id IN ' + idValues;
        List<SObject> outputMember = Database.query(queryString);

        List<List<SObject>> responseWrapper = new List<List<SObject>>();
        responseWrapper.add(outputMember);
        return responseWrapper;   
    }
    public class Requests {
        @InvocableVariable
        public String objectType;
        
        @InvocableVariable
        public String values;
    }
}

Best Answer

Change:

String queryString = 'SELECT Id, Name FROM ' + objInput.objectType + ' WHERE Id IN ' + idValues;

To:

String queryString = 'SELECT Id, Name FROM ' + objInput.objectType + ' WHERE Id IN :idValues';

This then uses a binding for the IN evaluation. To clarify, this works even in dynamic SOQL because this is a simple binding variable (I don't need to use anything more than a locally-accessible-at-time-of-query-execution variable's name. Dynamic SOQL doesn't support bindings that are more than a variable name, so cannot include function calls (()), property access (.) or array index access ([]) which you can use in static SOQL bindings.

Related Topic