web-dev-qa-db-fra.com

Échappe une chaîne dans SQL Server afin qu'elle puisse être utilisée en toute sécurité dans l'expression LIKE

Comment échapper à une chaîne de la procédure stockée de SQL Server afin de pouvoir l'utiliser en toute sécurité dans l'expression LIKE.

Supposons que j'ai une variable NVARCHAR comme ceci:

declare @myString NVARCHAR(100);

Et je veux l'utiliser dans une expression LIKE:

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

Comment puis-je échapper à la chaîne (plus précisément, les caractères significatifs pour LIKE correspondance de modèle, par exemple % ou ?) dans T-SQL, pour que vous puissiez utiliser cette méthode en toute sécurité?

Par exemple, étant donné:

@myString = 'aa%bb'

Je voudrais:

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

correspondre 'aa%bb', 'caa%bbc' mais non 'aaxbb' ou 'caaxbb'.

74
Artur

Pour échapper aux caractères spéciaux dans une expression LIKE, vous les préfixez avec un caractère d'échappement. Vous devez choisir le caractère d'échappement à utiliser avec le mot clé ESCAPE. ( MSDN Ref )

Par exemple, cela échappe au symbole%, en utilisant\comme caractère d'échappement:

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

Si vous ne savez pas quels caractères seront dans votre chaîne et si vous ne voulez pas les traiter comme des caractères génériques, vous pouvez préfixer tous les caractères génériques d'un caractère d'échappement, par exemple:

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

(Notez que vous devez également échapper votre caractère d'échappement et assurez-vous que c'est le replace intérieur afin de ne pas échapper à ceux ajoutés à partir des autres instructions replace.). Ensuite, vous pouvez utiliser quelque chose comme ceci:

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

Pensez également à allouer plus d’espace à votre variable @myString car elle s’allongera avec le remplacement de la chaîne.

90
Rory

Avait un problème similaire (en utilisant NHibernate, donc le mot clé ESCAPE aurait été très difficile) et résolu en utilisant les caractères entre crochets. Donc, votre échantillon deviendrait

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

Si vous avez besoin d'une preuve:

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
18

Plutôt que d'échapper à tous les caractères d'une chaîne qui ont une signification particulière dans la syntaxe du modèle, étant donné que vous utilisez un caractère générique dans le modèle, cela est plus rapide et plus simple. juste pour faire.

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

Dans les cas où vous n'utilisez pas de caractère générique de premier plan, l'approche ci-dessus doit être évitée, toutefois, elle ne peut pas utiliser d'index sur YourColumn.

De plus, dans les cas où le plan d’exécution optimal variera en fonction du nombre de lignes correspondantes, les estimations peuvent être meilleures si vous utilisez LIKE avec la syntaxe d'échappement entre crochets, par rapport à les deux CHARINDEX). et le mot clé ESCAPE .

13
Martin Smith

Vous spécifiez le caractère d'échappement. Documentation ici:
http://msdn.Microsoft.com/en-us/library/ms179859.aspx

4
Corey Trager

Voulez-vous rechercher des chaînes qui incluent un caractère d'échappement? Par exemple, vous voulez ceci:

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

Où voulez-vous rechercher tous les champs avec 10%? Si tel est le cas, vous pouvez utiliser la clause ESCAPE pour spécifier un caractère d'échappement et échapper le caractère générique.

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

Autre syntaxe d'échappement:

LIKE Wildcard Literals

Le pilote JDBC prend en charge la syntaxe {escape 'caractère d'échappement'} permettant d'utiliser les caractères génériques de la clause LIKE en tant que littéraux.

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

db <> démo de violon

0
Lukasz Szozda