Исключить строку в SQL Server, чтобы ее можно было использовать в выражении LIKE

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

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

declare @myString NVARCHAR(100);

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

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

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

Например, данный:

@myString = 'aa%bb'

Я хочу:

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

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

Ответ 1

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

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

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

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

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

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

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

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

Ответ 2

Имела аналогичную проблему (с использованием 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

Ответ 3

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

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

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

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

Ответ 5

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

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

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

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

Ответ 6

Альтернативный экранирующий синтаксис:

НРАВИТСЯ Wildcard Литералы

Драйвер JDBC поддерживает синтаксис {escape 'escape symbol'} для использования подстановочных знаков предложения LIKE в качестве литералов.

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

ДБ <> Fiddle Demo