LIKE 식에서 안전하게 사용할 수 있도록 SQL Server에서 문자열을 이스케이프합니다.


78

LIKE표현식 에서 안전하게 사용할 수 있도록 SQL Server의 저장 프로 시저에서 문자열을 이스케이프하려면 어떻게해야합니까?

다음 NVARCHAR과 같은 변수 가 있다고 가정합니다 .

declare @myString NVARCHAR(100);

그리고 LIKE식에서 사용하고 싶습니다 .

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

T-SQL에서 문자열 (더 구체적으로는 LIKE패턴 일치에 의미있는 문자 , 예를 들어 %또는 ?)을 어떻게 이스케이프하여 이러한 방식으로 사용하는 것이 안전합니까?

예를 들면 다음과 같습니다.

@myString = 'aa%bb'

내가 원하는:

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

일치합니다 'aa%bb', 'caa%bbc'하지만 'aaxbb''caaxbb'.

답변:


94

LIKE 표현식에서 특수 문자를 이스케이프하려면 이스케이프 문자를 접 두부로 붙입니다. ESCAPE 키워드와 함께 사용할 이스케이프 문자를 선택해야합니다. ( MSDN 참조 )

예를 들어 이스케이프 문자로 \를 사용하여 % 기호를 이스케이프합니다.

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

문자열에 어떤 문자가 포함 될지 모르고 와일드 카드로 취급하지 않으려면 모든 와일드 카드 문자 앞에 이스케이프 문자를 붙일 수 있습니다. 예 :

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

(이스케이프 문자도 이스케이프해야 replace하며 다른 replace문 에서 추가 된 항목을 이스케이프하지 않도록 내부 문자인지 확인해야합니다 .) 그런 다음 다음과 같이 사용할 수 있습니다.

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

또한 @myString 변수는 문자열 교체로 더 길어 지므로 더 많은 공간을 할당해야합니다.


현재 저는 stackoverflow.com/questions/13861004/에 언급 된 접근 방식을 사용 하고 있습니다… 그 코드에 어떤 단점이 있습니까?
LCJ

2
@ Lijo, 괜찮습니다. 그 대답은 C #에서 이스케이프를 수행하는 반면 위의 대답은 C #과 관련이 없기 때문에 SQL에서 수행합니다. 결과는 동일합니다. 검색 문자열에서 특수 문자를 이스케이프하고 LIKE 문에서 ESCAPE 키워드를 사용합니다.
Rory

나는 또한 작은 따옴표를 이스케이프해야한다고 생각합니다 (이 아닌 두 개의 작은 따옴표로 대체 \').
Ted Hopp 2014 년

@TedHopp-아니요, 'LIKE의 특수 문자가 아니기 때문에 LIKE를 위해 이스케이프 할 필요가 없습니다 . 예를 들어 이것은 잘 작동합니다.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

@TedHopp-아마도 당신이 언급하는 것은 '문자열 상수에서 작은 따옴표를 정의하기 위해 두 개를 사용해야한다는 것 입니다. 예, 그렇게해야하지만 결과 문자열 값에는 작은 따옴표 만 있습니다. 이스케이프는 상수 값으로 선언 할 때 작은 따옴표를 문자열 변수로 가져 오기 위해 수행됩니다. '어딘가에서를 선택할 수 있으며 탈출 할 필요가 없습니다.
Rory 2014 년

19

비슷한 문제 (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

1
이것이 최고의 답변입니다. 이스케이프에 의존하지 않고 모든 문자열에서 작동합니다.
John

나는 이것이 가장 간단하고 질문자가 찾고 있던 것에 가장 가깝다고 생각합니다. ESCAPE가 어떤 경우에는 유용하지 않다는 것은 아닙니다.
bitoolean

2
이스케이프가 필요한 문자 목록을 안정적으로 얻는 방법이나 임의의 문자열을 가져와 적절하게 이스케이프하는 방법에 대한 설명은 아직 없습니다.
binki

14

패턴에서 선행 와일드 카드를 사용하는 경우 패턴 구문에서 특별한 의미가있는 문자열의 모든 문자를 이스케이프 하는 것보다 더 빠르고 쉽게 수행 할 수 있습니다.

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

선행 와일드 카드를 사용하지 않는 경우 위의 접근 방식은에서 인덱스를 사용할 수 없으므로 피해야합니다 YourColumn.

또한 최적의 실행 계획 사용시 추정치 좋을 수도 매칭 행의 수에 따라 달라질 수있는 경우 LIKE에 비해 구문 탈출 대괄호로 모두CHARINDEX키워드 .ESCAPE


우수한! 하지만 선행 와일드 카드가 없다면 어떨까요?
Colin

1
@Colin-선행 와일드 카드가없고 문자열의 다른 위치에있는 모든 와일드 카드 문자 를 이스케이프하는 것이 목적 이라면 =대신 사용할 수 있습니다 . 이스케이프 특수 문자 답변은 특정 값으로 시작하는 값을 찾는 쿼리에 여전히 유용 LIKE할 수 있지만이 경우 인덱스를 사용할 CHARINDEX수 있지만 사용할 수 없습니다.
Martin Smith


3

이스케이프 문자가 포함 된 문자열을 찾으시겠습니까? 예를 들어 다음을 원합니다.

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

10 %가 포함 된 모든 필드를 어디에서 검색 하시겠습니까? 이 경우 ESCAPE 절을 사용하여 이스케이프 문자를 지정하고 와일드 카드 문자를 이스케이프 할 수 있습니다.

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

질문에 제가 원하는 예를 추가했습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.