LIKE
式で安全に使用できるように、SQL Serverのストアドプロシージャの文字列をエスケープするにはどうすればよいですか。
次のようなNVARCHAR
変数があるとします。
declare @myString NVARCHAR(100);
そして、LIKE
式で使用したい:
... WHERE ... LIKE '%' + @myString + '%';
文字列(より具体的には、LIKE
パターンマッチングに意味のある文字、たとえば%
または ?
)T-SQLでは、この方法で安全に使用できますか?
たとえば、次の場合:
@myString = 'aa%bb'
が欲しいです:
WHERE ... LIKE '%' + @somehowEscapedMyString + '%'
合わせる 'aa%bb'
、'caa%bbc'
だがしかし 'aaxbb'
または 'caaxbb'
。
LIKE式の特殊文字をエスケープするには、エスケープ文字を接頭辞として使用します。 ESCAPEキーワードで使用するエスケープ文字を選択できます。 ( MSDN Ref )
たとえば、これは、エスケープ文字として\を使用して、%記号をエスケープします。
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変数には、文字列の置換により長くなるため、より多くのスペースを割り当てることを忘れないでください。
同様の問題があり(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
パターンで先頭のワイルドカードを使用している場合、パターン構文で特に重要な文字列内のall文字をエスケープするのではなく、より速く簡単ですただやる。
SELECT *
FROM YourTable
WHERE CHARINDEX(@myString , YourColumn) > 0
先頭のワイルドカードを使用していない場合は、YourColumn
のインデックスを使用できないため、上記のアプローチは避けてください。
さらに、最適な実行プランが一致する行の数によって異なる場合、 both LIKE
と比較して、CHARINDEX
と角括弧エスケープ構文を使用すると、推定値が向上する場合があります。 =および ESCAPE
キーワード 。
エスケープ文字を指定します。ここにドキュメント:
http://msdn.Microsoft.com/en-us/library/ms179859.aspx
エスケープ文字を含む文字列を探しますか?たとえば、これが必要です:
select * from table where myfield like '%10%%'.
10%ですべてのフィールドを検索する場所その場合、ESCAPE句を使用してエスケープ文字を指定し、ワイルドカード文字をエスケープできます。
select * from table where myfield like '%10!%%' ESCAPE '!'
代替エスケープ構文:
JDBCドライバーは、LIKE句のワイルドカードをリテラルとして使用するための{escape 'escape character'}構文をサポートします。
SELECT *
FROM tab
WHERE col LIKE 'a\_c' {escape '\'};