When using the SOQL LIKE operator in Salesforce Apex to match a search term that includes a reserved character — such as an underscore (_) — the standard escape sequence may not work as expected when written directly as a string literal inside a SOQL query in Apex code.
In SOQL, the underscore character (_) is a wildcard that matches any single character. To search for a literal underscore in a LIKE expression, you must escape it using a backslash: \_. However, when this escape sequence is written directly as a string literal inside a SOQL query embedded in Apex code, the Apex string parser processes the backslash before the SOQL engine does. As a result, the escape does not work correctly and the query matches more records than expected.
For example, if you have Account records named namea, name_a, and name_b, and you write a SOQL query using LIKE '%\\_a' directly in the query string, the assertion for one row (name_a) fails because the escape sequence is not applied correctly by the SOQL engine.
@isTest
private static void testWithoutAssignment()
{
insert new account(name='namea');
insert new account(name='name_a');
insert new account(name='name_b');
List<Account> a = [SELECT Name From Account Where Name like '%\\_a'];
system.debug(a);
system.assertEquals(1,a.size()); // fails
}
The fix is to assign the SOQL search term — including the escape sequence — to a separate Apex String variable first, and then use that variable as a bind variable in the SOQL query using the colon (:) bind syntax.
When the search term is assigned to a variable, the Apex string parser and the SOQL engine process the value correctly and independently. The escape sequence in the Apex string is then correctly interpreted by SOQL as an escaped underscore — meaning "match a literal underscore character, not any single character."
Declare a String variable and assign your search term with the escape sequence as the value. For example:String searchTerm = '%\\_a';
Then use that variable as a bind variable in your SOQL query:WHERE Name LIKE :searchTerm
The query now correctly matches only records where the Name field ends with the literal characters _a. In the example with records namea, name_a, and name_b, the query returns only name_a.
In Apex string literals, \\ represents a single backslash character. When you write '%\\_a' in an Apex string, the resulting string value stored in the variable contains %\_a. When SOQL receives this bind variable value, it correctly interprets \_ as an escaped underscore wildcard — meaning match only a literal underscore character, not any character. This produces the expected result of matching name_a but not namea or name_b.
@isTest
private static void testWithAssignment()
{
insert new account(name='namea');
insert new account(name='name_a');
insert new account(name='name_b');
String searchTerm = '%\\_a'; // assign the search term to a variable
List<Account> a = [SELECT Name From Account Where Name like :searchTerm];
system.debug(a);
system.assertEquals(1,a.size()); // success
}000382866

We use three kinds of cookies on our websites: required, functional, and advertising. You can choose whether functional and advertising cookies apply. Click on the different cookie categories to find out more about each category and to change the default settings.
Privacy Statement
Required cookies are necessary for basic website functionality. Some examples include: session cookies needed to transmit the website, authentication cookies, and security cookies.
Functional cookies enhance functions, performance, and services on the website. Some examples include: cookies used to analyze site traffic, cookies used for market research, and cookies used to display advertising that is not directed to a particular individual.
Advertising cookies track activity across websites in order to understand a viewer’s interests, and direct them specific marketing. Some examples include: cookies used for remarketing, or interest-based advertising.