87

How do I escape a string in SQL Server's stored procedure so that it is safe to use in LIKE expression.

Suppose I have an NVARCHAR variable like so:

declare @myString NVARCHAR(100);

And I want to use it in a LIKE expression:

... WHERE ... LIKE '%' + @myString + '%';

How do I escape the string (more specifically, characters that are meaningful to LIKE pattern matching, e.g. % or ?) in T-SQL, so that it is safe to use in this manner?

For example, given:

@myString = 'aa%bb'

I want:

WHERE ... LIKE '%' + @somehowEscapedMyString + '%'

to match 'aa%bb', 'caa%bbc' but not 'aaxbb' or 'caaxbb'.

embedded.kyle
  • 10,976
  • 5
  • 37
  • 56

6 Answers6

108

To escape special characters in a LIKE expression you prefix them with an escape character. You get to choose which escape char to use with the ESCAPE keyword. (MSDN Ref)

For example this escapes the % symbol, using \ as the escape char:

select * from table where myfield like '%15\% off%' ESCAPE '\'

If you don't know what characters will be in your string, and you don't want to treat them as wildcards, you can prefix all wildcard characters with an escape char, eg:

set @myString = replace( 
                replace( 
                replace( 
                replace( @myString
                ,    '\', '\\' )
                ,    '%', '\%' )
                ,    '_', '\_' )
                ,    '[', '\[' )

(Note that you have to escape your escape char too, and make sure that's the inner replace so you don't escape the ones added from the other replace statements). Then you can use something like this:

select * from table where myfield like '%' + @myString + '%' ESCAPE '\'

Also remember to allocate more space for your @myString variable as it will become longer with the string replacement.

Rory
  • 40,559
  • 52
  • 175
  • 261
  • Currently I am using approach mentioned in http://stackoverflow.com/questions/13861004/escaping-the-escape-character-does-not-work-sql-like-operator Do you see any shortcomings with that code? – LCJ Dec 13 '12 at 14:57
  • 2
    @Lijo, that's fine. That answer does the escaping in C# whereas the above answer does it in SQL as it's not C#-specific. Either way the result is the same: escape any special chars in your search string and use the ESCAPE keyword in your LIKE statement. – Rory Dec 13 '12 at 18:46
  • I think you also need to escape a single quote (replacing it with two single quotes, not with `\'`). – Ted Hopp Sep 05 '14 at 17:19
  • @TedHopp - no, you don't need to escape `'` for the purposes of LIKE, because it's not a special character for LIKE. For example this works fine: `declare @s nvarchar(max); set @s = '%''%'; with a_cte as ( select 'I''m adam' as aColumn ) select * from a_cte where aColumn like @s;` – Rory Sep 06 '14 at 14:30
  • @TedHopp - what you're probably referring to is just the need to use two `'` in order to define a single quote in a string constant. Yes you need to do that, but the resulting string value only has a single quote: the escaping is done just to get the single quote into the string variable when declaring it as a constant value. You could select the `'` from somewhere and wouldn't need to escape it. – Rory Sep 06 '14 at 14:35
  • ...In the case of LIKE special chars the string value actually contains the escape character. So if you `print @myString` from my answer you'll see values like `15\% off` but if you `print @s` from my previous comment it will just look like `%'%`, i.e. just a single quote. – Rory Sep 06 '14 at 14:37
19

Had a similar problem (using NHibernate, so the ESCAPE keyword would have been very difficult) and solved it using the bracket characters. So your sample would become

WHERE ... LIKE '%aa[%]bb%'

If you need proof:

create table test (field nvarchar(100))
go
insert test values ('abcdef%hijklm')
insert test values ('abcdefghijklm')
go
select * from test where field like 'abcdef[%]hijklm'
go
  • 1
    This is the best answer. Doesn't rely on escape and works for all strings. – John May 21 '17 at 20:37
  • I think this is the simplest and so closest to what the asker was looking for. Not to say that ESCAPE is not as useful in some cases. – bitoolean Jan 09 '18 at 14:57
  • 2
    Still there’s no explanation of how to reliably get a list of characters which need escaping or how to take an arbitrary string and properly escape it. – binki Apr 11 '18 at 02:02
15

Rather than escaping all characters in a string that have particular significance in the pattern syntax given that you are using a leading wildcard in the pattern it is quicker and easier just to do.

SELECT * 
FROM YourTable
WHERE CHARINDEX(@myString , YourColumn) > 0

In cases where you are not using a leading wildcard the approach above should be avoided however as it cannot use an index on YourColumn.

Additionally in cases where the optimum execution plan will vary according to the number of matching rows the estimates may be better when using LIKE with the square bracket escaping syntax when compared to both CHARINDEX and the ESCAPE keyword.

Community
  • 1
  • 1
Martin Smith
  • 438,706
  • 87
  • 741
  • 845
  • Excellent! But what if there was no leading wild card? – Colin Apr 28 '12 at 16:28
  • 1
    @Colin - If there was no leading wildcard and the aim was to escape **all** wild card characters elsewhere in the string then you could just use `=` instead. The escaping special characters answers could still be useful for a query looking for values starting with a particular value though as `LIKE` can use an index in that case but `CHARINDEX` can't. – Martin Smith Apr 28 '12 at 16:54
4

You specify the escape character. Documentation here:
http://msdn.microsoft.com/en-us/library/ms179859.aspx

Corey Trager
  • 22,649
  • 18
  • 83
  • 121
  • 1
    I was wishing for something that already nows what needs to be escaped in a LIKE expression. –  Nov 03 '08 at 14:31
  • The answer suggested you specify your own escape character so "meaningful " characters will not be meaningful anymore. – Goran Nov 03 '08 at 14:38
3

Do you want to look for strings that include an escape character? For instance you want this:

select * from table where myfield like '%10%%'.

Where you want to search for all fields with 10%? If that is the case then you may use the ESCAPE clause to specify an escape character and escape the wildcard character.

select * from table where myfield like '%10!%%' ESCAPE '!'
Vincent Ramdhanie
  • 102,349
  • 23
  • 137
  • 192
0

Alternative escaping syntax:

LIKE Wildcard Literals

The JDBC driver supports the {escape 'escape character'} syntax for using LIKE clause wildcards as literals.

SELECT *
FROM tab
WHERE col LIKE 'a\_c' {escape '\'};

db<>fiddle demo

Lukasz Szozda
  • 162,964
  • 23
  • 234
  • 275