SQLServer(データベース)のテーブルに対してデータを抽出したり、データを更新したりする際にLIKE演算子を利用すると、ワイルドカードが利用できます。
SQLServerのLIKE演算子で使用できるワイルドカードには「%」や「_」などがありますが、「%」や「_」を検索条件に含めたい場合は、ワイルドカードをエスケープしなければなりません。
今回の記事では、SQLServerに対してLIEK演算子を使用してワイルドカードとして利用できる文字列や特殊文字を検索条件に含める際のエスケープ処理について紹介します。
LIKE検索
LIKE演算子を使用することで、や前方一致や後方一致、または部分一致での検索が可能になります。
例えば、「顧客」テーブルの「顧客名」列に対して先頭が「あ」で始まるレコード(前方一致するレコード)を抽出する場合は、以下のようなSQLを記述します。
1 2 3 4 5 6 |
SELECT * FROM 顧客 WHERE 顧客名 LIKE 'あ%' |
「顧客名」のどこかに「あ」が含まれているレコード(部分一致するレコード)を抽出する場合は、以下のようになります。
1 2 3 4 5 6 |
SELECT * FROM 顧客 WHERE 顧客名 LIKE '%あ%' |
ここでは、任意の文字列を表すワイルドカードの「%」をLIKE演算子を使用して条件に指定しています。
LIKE演算子で使用するワイルドカード文字を検索条件に含める
上記の顧客テーブルに対するデータの抽出で、今度は「%」という文字を含むデータを前方一致で検索したい場合について考えてみます。
単純にWHERE句での条件を
1 2 |
WHERE 顧客名 LIKE '%%' |
とすると、すべてのレコードが抽出対象となってしまいます。
これは、「%」と「%」で囲われた部分が、空文字列も含む任意の文字列に部分一致しているためです。
このような場合にはワイルドカードの「%」をそのまま記述してもうまく検索条件として照合することができません。
そこで、SQLServerではLIKE演算子を使用した検索の条件にワイルドカードなどの特殊文字を指定するために括弧([])を使用します。
括弧「[」と「]」で通常の文字として認識させたい文字を囲みます。
「%」を認識させる場合は「[%]」
「_」を認識させる場合は「[_]」
となります。
エスケープに使用する「[」(前括弧)自体も特殊文字になりますので、「[」を文字として認識させるためには「[[]」と指定します。
プログラムから条件を指定する際の処理
ここでは、C#を例にプログラムからSQLServerにSQLを発行して問い合わせる際に、LIKE演算子に指定する文字列をエスケープする処理を記載します。
以下のメソッドでは、LIKE演算子で使用する条件に指定する文字列をエスケープしています。
1 2 3 4 5 |
public string EscapeSqlLikeCondition(string condition) { var replaced = condition.Replace("[", "[[]").Replace("%", "[%]").Replace("_", "[_]"); return replaced ; } |
StringクラスのReplaceメソッドを利用すると上記のような処理を行うことで、ワイルドカードなどの特殊文字をエスケープすることができます。
また、特殊文字をエスケープする処理は正規表現を利用して行うこともできます。
1 2 3 4 5 6 |
public string EscapeSqlLikeCondition(string condition) { var replaced = Regex.Replace(condition, @"[%_\[]", "[$0]"); return replaced ; } // using System.Text.RegularExpressions;が必要です。 |
正規表現のRegexクラスのReplaceメソッドを利用して「%」「_」「[」を置換しています。
上記のメソッドを使用した例を以下に示します。
ここでは「%」と「_」と「[」を含む「あ%い_う[え」という文字列をLIKE演算子の条件に指定したSQL文字列を作成しています。
1 2 3 4 5 6 7 8 9 |
var likeSql = EscapeSqlLikeCondition2("あ%い_う[え"); var sql = $@" SELECT * FROM 顧客 WHERE 顧客名 LIKE '{likeSql}' "; |
上記の処理を行うと、変数sqlには以下の文字列が格納されます。
1 2 3 4 5 6 |
SELECT * FROM 顧客 WHERE 顧客名 LIKE 'あ[%]い[_]う[[]え' |