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'
.
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.
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
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
.
Vous spécifiez le caractère d'échappement. Documentation ici:
http://msdn.Microsoft.com/en-us/library/ms179859.aspx
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 '!'
Autre syntaxe d'échappement:
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 '\'};