Skip to main content
added 103 characters in body
Source Link
Adrian Larson
  • 151.3k
  • 38
  • 247
  • 431

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're depending on type coercion from Set to String, which is never a good idea. 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'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
);
Source Link
Adrian Larson
  • 151.3k
  • 38
  • 247
  • 431

You're depending on type coercion from Set to String, which is never a good idea. 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
);