I'm trying to create a dynamic SOQL string based on the type of fields being used. If the field is a text area, it contains a list of comma delimited strings. For each text area field, I create a list of the delimited values, and use "IN :TAValues" in the dynamic SOQL.

Problem is, if there is more than one text area field, the values in 'TAValues' get overwritten by the last field evaluated in the loop. I can't use a map or TAValues[i] in the dynamic query - how could this be done?

        public Map<String, String> CriteriaFieldNameToValue = new Map<String, String>();

        String QString = 'SELECT ID, Name FROM Account WHERE ';   
        Map<String, Schema.SObjectField> fieldMap = ((SObject)Type.forName('Schema','Account_Rule__c').newInstance()).getSObjectType().getDescribe().fields.getMap();           
        for (String FieldName: CriteriaFieldNameToValue.keySet()){  
            String FieldValue = CriteriaFieldNameToValue.get(FieldName);
            String FieldType = String.valueof(fieldMap.get(FieldName).getDescribe().getType());
            system.debug(FieldName +' = '+FieldValue);            
            if(FieldType == 'TEXTAREA'){
                String [] TAValues = FieldValue.split(',');
                QString = QString + FieldName +' IN :TAValues AND ';
                    system.debug('QString = '+QString);
                    system.debug('TAValues = '+TAValues);
        QString = QString.removeEndIgnoreCase(' AND ');
            system.debug('QString = '+QString);
        return Database.getQueryLocator(QString);   

1 Answer 1


In this scenario it is impossible to use bindings and you must instead "inline" the actual values, generating the query string so it looks like:

... Xyz IN ('value 1', 'value 2', ...) ...

The most important point here is that each value must be escaped to ensure no SOQL Injection vulnerability. Do that for each value using String.escapeSingleQuotes.

The generation can be performed in two steps:


List<String> escapedValues = new List<String>();

// escape the values to avoid SOQL Injection vulnerabilities
for (String value : values) {

// generate the SOQL filtering term
String term = fieldName + ' IN (\'' + String.join(escapedValues, '\', \'') + '\')';


By the way, the above approach of using String.join is ideal for combining multiple clauses together with ') AND (' as the delimiter and an initial open and trailing close bracket outside the join. This avoids messing with removing trailing text.

You must log in to answer this question.

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