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.