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
);