2008-11-03 18 views
65

Jak uzyskać uniknięcie ciągu znaków w przechowywanej procedurze programu SQL Server, aby można było bezpiecznie używać wyrażenia LIKE.Uciec łańcuch w programie SQL Server, aby można go było bezpiecznie używać w wyrażeniu LIKE

Załóżmy, że mam zmienną NVARCHAR tak:

declare @myString NVARCHAR(100); 

I chcę, aby użyć go w LIKE wyrażenia:

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

Jak mogę uciec ciąg (a dokładniej, znaki mają znaczenie w dopasowywaniu wzorców do LIKE, np. % lub ?) w języku T-SQL, aby można go było bezpiecznie używać w ten sposób?

Na przykład, biorąc pod uwagę:

@myString = 'aa%bb' 

chcę:

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

dopasować 'aa%bb', 'caa%bbc' ale nie 'aaxbb' lub 'caaxbb'.

+0

Nie umieściłeś swojego języka programowania w –

+0

Jego językiem programowania jest T-SQL. –

Odpowiedz

81

Aby uniknąć znaków specjalnych w wyrażeniu LIKE, należy poprzedzić je znakiem escape. Możesz wybrać, który znak kontrolny będzie używany ze słowem kluczowym ESCAPE. (MSDN Ref)

Na przykład ten ucieka symbolem%, stosując jako \ char ucieczki:

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

Jeśli nie wiesz, jakie znaki będą w ciągu, a ty nie chcesz traktować je jako symbole wieloznaczne, można poprzedzić wszystkie znaki wieloznaczne z char ewakuacyjnej, np:

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

(należy pamiętać, że trzeba uciekać swoją postać ucieczki też, i upewnić się, że to wewnętrzna replace więc nie uciekać te dodane od innych replace wyciągów). Następnie można użyć mniej więcej tak:

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

Należy również pamiętać, aby przeznaczyć więcej miejsca na zmienną @myString jak będzie się on już z wymianą strun.

+0

Obecnie używam podejścia wspomnianego w http://stackoverflow.com/questions/13861004/escaping-the-escape-character-does-not-work-sql-like-operator Czy widzisz jakieś niedociągnięcia z tym kodem? – Lijo

+2

@Lijo, w porządku. Ta odpowiedź robi ucieczkę w C#, podczas gdy powyższa odpowiedź robi to w SQL, ponieważ nie jest specyficzna dla C#. Tak czy inaczej wynik jest taki sam: unikaj znaków specjalnych w ciągu wyszukiwania i użyj słowa kluczowego ESCAPE w instrukcji LIKE. – Rory

+0

Myślę, że musisz uciec od pojedynczego cudzysłowu (zastępując go dwoma pojedynczymi cytatami, a nie '\ ''). –

5

Podajesz znak ucieczki. Dokumentacja:
http://msdn.microsoft.com/en-us/library/ms179859.aspx

+1

Pragnąłem czegoś, co już zawiera to, co trzeba uciec w wyrażeniu LIKE. –

+0

Odpowiedź zasugerowała, abyś określił własną postać ucieczki, więc "znaczące" postacie nie będą już miały znaczenia. – Goran

3

Czy chcesz wyszukać ciągi zawierające znak ucieczki? Na przykład chcesz:

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

Gdzie chcesz wyszukać wszystkie pola z 10%? W takim przypadku możesz użyć klauzuli ESCAPE do określenia znaku escape i uniknięcia znaku wieloznacznego.

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

Dodałem przykład tego, co chcę na to pytanie. –

16

Miał podobny problem (używając NHibernate, więc słowo kluczowe ESCAPE byłoby bardzo trudne) i rozwiązał je, używając znaków nawiasów.Więc próbka stanie się

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

Jeśli potrzebujesz dowodu:

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 
+0

To jest najlepsza odpowiedź. Nie polega na ucieczce i działa dla wszystkich łańcuchów. – John

+0

Myślę, że jest to najprostszy i najbliżej tego, czego szukał pytający. Nie można powiedzieć, że ESCAPE nie jest tak przydatne w niektórych przypadkach. – bitoolean

12

zamiast ucieczki wszystkie znaków w ciągu, które mają szczególne znaczenie w składni wzór podano, że używasz wiodącą wieloznacznego we wzorcu jest to szybsze i łatwiejsze do zrobienia.

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

W przypadkach, gdy nie korzystają wiodącą wieloznaczny podejście powyżej powinny być unikane, ponieważ jednak nie można używać indeksu na YourColumn.

Ponadto w przypadkach, gdy optymalna plan wykonania różni się w zależności od liczby rzędów odpowiadających oszacowania może być lepsze przy stosowaniu LIKE z kwadratowego składni ucieczki w porównaniu z both CHARINDEX i the ESCAPE keyword wspornika.

+0

Doskonale! Ale co, jeśli nie ma wiodącej, dzikiej karty? – Colin

+1

@Colin - Jeśli nie było wiodącego symbolu wieloznacznego, a celem było uciec ** wszystkie znaki wieloznaczne w innym miejscu ciągu znaków, można zamiast tego użyć '='. Odpowiedzi znaków specjalnych mogą być przydatne dla zapytania szukającego wartości zaczynających się od konkretnej wartości, ponieważ 'LIKE' może używać indeksu w tym przypadku, ale' CHARINDEX' nie może. –

Powiązane problemy