0

The below code can be executed in Anonymous window. I have seen this code working before.

I am expecting qProdList to return exact number of records that i pass in the set "st".I am passing 18 items in st. But the number of product records returned by qProdList is always 10 records.

I have verified all these 18 items in the database, and all are present. only post I am applying string operation it results in 10 items.

Please advice what could be the reason string operation is behaving inconsistent in apex?

set<string> st = new set<String>{'A,'B','C','D','E','F','G,'S,'Q','N','M','Y','O','P,'J,'K,'I','H'};

system.debug('st : ' + st.size() + '--' + st);

string b = string.valueof(st).split('[{}]')[1];

system.debug('b : ' + b);

string qProd = 'select isActive,ProductCode from Product2 where isActive = true and  ProductCode IN (\''+ b.replaceAll('\\, ','\',\'')+'\')'; 

system.debug('qProd : + ' + qProd); 

list<Product2> qProdList = Database.query(qProd); 

system.debug(' --  qProdList  -- : ' + qProdList.size()); 
1
  • You don't need to use string manipulation to construct a SOQL query like this. You can use an IN operator with a bound set object, or construct a dynamic query by doing String.join() on the set.
    – David Reed
    Commented Apr 12, 2018 at 14:22

1 Answer 1

5

You're depending on type coercion from Set to String, which is never a good idea. The specific problem here is that String.valueOf on any collection will truncate at ten elements.

Your options here are:

  • bind the value dynamically
  • build the query string explicitly

Examples:

Set<String> values = new Set<String> { ... };
List<Product2> records = Database.query(
    'SELECT ... FROM Product2 WHERE ProductCode IN :values'
);

// even better to just use a static query if you can
List<Product2> preferredQuery = [
    SELECT ... FROM Product2 WHERE ProductCode IN :values
];

- OR -

// if the input is coming from an untrusted source,
// escape to avoid injection vulnerability
Set<String> values = new Set<String> { ... };
List<String> escaped = new List<String>();
for (String value : values) escaped.add(String.escapeSingleQuotes(value));

String filter = '(' + String.join(escaped, ',') + ')';
// now you have a literal filter you can merge in with exactly the values as you expect
// e.g. ('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M')

List<Product2> records = Database.query(
    'SELECT ... FROM Product2 WHERE ProductCode IN ' + filter
);

You must log in to answer this question.

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