Escape-строка в SQL Server, чтобы ее можно было безопасно использовать в выражении LIKE. - PullRequest
73 голосов
/ 03 ноября 2008

Как экранировать строку в хранимой процедуре SQL Server, чтобы ее можно было безопасно использовать в выражении LIKE.

Предположим, у меня есть переменная NVARCHAR, например:

declare @myString NVARCHAR(100);

И я хочу использовать его в выражении LIKE:

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

Как мне избежать строки (точнее, символов, которые имеют значение для LIKE сопоставления с образцом, например, % или ?) в T-SQL, чтобы можно было безопасно использовать таким образом? 1015 *

Например, учитывая:

@myString = 'aa%bb'

Я хочу:

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

для соответствия 'aa%bb', 'caa%bbc', но не 'aaxbb' или 'caaxbb'.

Ответы [ 5 ]

90 голосов
/ 03 ноября 2008

Чтобы экранировать специальные символы в выражении LIKE, перед ними необходимо использовать экранирующий символ. Вы можете выбрать, какой escape-символ использовать с ключевым словом ESCAPE. ( MSDN Ref )

Например, это экранирует символ%, используя \ в качестве escape-символа:

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

Если вы не знаете, какие символы будут в вашей строке, и не хотите рассматривать их как символы подстановки, вы можете использовать префикс всех символов подстановки с помощью escape-символа, например:

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

(Обратите внимание, что вы также должны экранировать свой escape-символ, и убедитесь, что это внутренний replace, чтобы вы не избегали тех, которые добавлены из других операторов replace). Тогда вы можете использовать что-то вроде этого:

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

Также не забудьте выделить больше места для вашей переменной @myString, так как она станет больше при замене строки.

18 голосов
/ 24 июля 2009

Была похожая проблема (с использованием NHibernate, поэтому ключевое слово ESCAPE было бы очень сложно), и она решалась с помощью символов в скобках. Таким образом, ваш образец станет

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

Если вам нужны доказательства:

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
13 голосов
/ 11 февраля 2012

Вместо экранирования всех символов в строке, которые имеют особое значение в синтаксисе шаблона, учитывая, что в шаблоне используется главный подстановочный знак, его проще и быстрее сделать.

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

В тех случаях, когда вы не используете начальный подстановочный знак, следует избегать вышеуказанного подхода, поскольку он не может использовать индекс для YourColumn.

Кроме того, в случаях, когда оптимальный план выполнения будет варьироваться в зависимости от количества совпадающих строк, оценки могут быть лучше при использовании LIKE с синтаксисом, заключенным в квадратные скобки, по сравнению с и CHARINDEX и ключевое слово ESCAPE .

4 голосов
/ 03 ноября 2008

Вы указываете escape-символ. Документация здесь:
http://msdn.microsoft.com/en-us/library/ms179859.aspx

3 голосов
/ 03 ноября 2008

Вы хотите найти строки, которые содержат escape-символ? Например, вы хотите это:

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

Где вы хотите найти все поля с 10%? В этом случае вы можете использовать предложение ESCAPE, чтобы указать escape-символ и экранировать подстановочный знак.

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