はじめに
MySQL、PostgreSQL、Oracleなどでは標準で正規表現(REGEXPやREGEXP_LIKEなど)が使えますが、SQL Serverでは長らく標準機能としての正規表現が存在せず、LIKE・NOT LIKE・PATINDEX・CHARINDEXを組み合わせて「正規表現っぽいこと」を実現するのが定石でした。
ただし2025年末に登場した SQL Server 2025(バージョン17.x) では、ついにネイティブの正規表現関数が追加されています。そのため本記事では、
- 従来からの
LIKE・PATINDEXを使った代替パターン集 - SQL Server 2025で使えるようになった正規表現関数の概要
の両方をまとめます。SQL Server 2022以前の環境で運用している方は1.の内容がそのまま実務で使えますし、SQL Server 2025以降への移行を検討している方は2.も合わせて参考にしてください。
お知らせ(採用情報)
最後にお知らせとなりますが、AppTime では一緒に働くメンバーを募集しております。
詳しくは採用情報ページをご確認ください。
みなさまからのご応募をお待ちしております。
1. まず結論:バージョンで対応状況が変わる
| 環境 | 正規表現 | 代替手段 |
|---|---|---|
| SQL Server 2022以前 | ❌ 標準では使えない |
LIKE / PATINDEX / CHARINDEX / CLR関数 |
| SQL Server 2025(17.x)、互換性レベル170以上 | ✅ REGEXP_LIKE等が使える |
(そのまま正規表現を利用可能) |
| Azure SQL Database / Managed Instance(最新更新ポリシー) | ✅ 使える | (そのまま正規表現を利用可能) |
互換性レベルが170未満のデータベースではREGEXP_LIKE系の関数自体が使えないため、オンプレ環境やレガシーシステムでは依然として本記事の前半で紹介するLIKE系のテクニックが重要になります。
2. SQL ServerのLIKEで使えるワイルドカード
| 記号 | 意味 |
|---|---|
% |
0文字以上の任意の文字列 |
_ |
任意の1文字 |
[ ] |
角かっこ内のいずれか1文字(文字クラス) |
[^ ] |
角かっこ内に含まれないいずれか1文字(否定文字クラス) |
[a-z] |
a〜zの範囲のいずれか1文字(範囲指定) |
%・_に加えて、角かっこによる文字クラス・範囲指定・否定指定が使えるのがSQL Server独自の拡張で、これが「正規表現っぽい」表現力の正体です。逆に、繰り返し量指定子(+ * {n,m})やグループ化(( ) |)はLIKEには存在しないため、ここは妥協が必要です。
3. 基本パターン集
任意の1文字
WHERE ColumnName LIKE 'A_'
| 入力 | 結果 |
|---|---|
| AB | OK |
| AC | OK |
| ABC | NG(2文字を超える) |
任意の文字列(前方一致)
WHERE ColumnName LIKE 'ABC%'
| 入力 | 結果 |
|---|---|
| ABC123 | OK |
| ABCXYZ | OK |
| AB123 | NG |
数字のみ
WHERE ColumnName NOT LIKE '%[^0-9]%'
| 入力 | 結果 |
|---|---|
| 12345 | OK |
| 123A5 | NG |
| 12-34 | NG |
半角英字のみ
WHERE ColumnName NOT LIKE '%[^a-zA-Z]%'
半角英数字のみ
WHERE ColumnName NOT LIKE '%[^a-zA-Z0-9]%'
これらは「否定文字クラスに1文字も該当しない」=「全文字が許可リストに含まれる」という発想で組み立てています。NOT LIKE '%[^許可文字]%'は実務で非常によく使う型なので、まず覚えておくと応用が効きます。
4. 実践例:英数字・ハイフン・カッコ・アスタリスクのみ許可する
製品型式コードなどで、半角英数字に加えて次の記号だけを許可したいケースを考えます。
- ハイフン
- - カッコ
( ) - アスタリスク
*
WHERE ColumnName NOT LIKE '%[^a-zA-Z0-9()*-]%'
| 入力 | 結果 |
|---|---|
| ABC-123 | OK |
| ABC(123) | OK |
| ABC* | OK |
| A1-B2(C3) | OK |
| ABC_123 | NG(アンダースコアは許可していない) |
| ABC/123 | NG |
| 株式会社ABC | NG(全角文字) |
| ABC@ | NG |
ハイフンを文字クラスの末尾に置いている点に注目してください。理由は後述の「注意点①」で説明します。
5. ブランク(NULL・空文字)も許可したい場合
入力が任意項目で、未入力もOKにしたい場合は次のように条件を追加します。
WHERE
ColumnName IS NULL
OR ColumnName = ''
OR ColumnName NOT LIKE '%[^a-zA-Z0-9()*-]%'
SQL ServerのLIKEはオペランドにNULLが含まれると結果もNULL(=WHERE句では不一致扱い)になります。そのためIS NULLの判定を別途用意する必要がある点が地味なつまずきポイントです。
6. 末尾スペースのみ許可したい場合
以下は許可したいパターンです(末尾に半角スペースが付いているだけ)。
ABC␣
ABC␣␣
ABC
逆に、文字の間にスペースが入る次のようなパターンはNGにしたい、というケースです。
AB C
A␣BC
この場合は2つの条件を組み合わせます。
WHERE
ColumnName NOT LIKE '%[^a-zA-Z0-9()* -]%'
AND RTRIM(ColumnName) NOT LIKE '% %'
- 1つ目の条件:許可文字にスペースも加えた文字クラスチェック
- 2つ目の条件:
RTRIMで末尾の空白を除去したうえで、まだ空白が残っていないかチェック
RTRIMは末尾の空白しか削らないため、文字の途中(または先頭)にスペースがあればRTRIM後も'% %'に一致し、NOT LIKEがFALSEとなって除外される、という仕組みです。
7. PATINDEXで違反文字の位置を特定する
PATINDEXを使うと、許可されていない文字が何文字目にあるかを取得できます。データクレンジングの際に非常に重宝します。
SELECT
ColumnName,
PATINDEX('%[^a-zA-Z0-9()*-]%', ColumnName) AS ErrorPosition
FROM SampleTable
例えばABC@123であれば、@がある位置(4文字目)が返ります。戻り値が0の場合は「違反文字なし」を意味するので、WHERE PATINDEX(...) > 0とすればNG行だけを抽出できます。
SELECT *
FROM SampleTable
WHERE PATINDEX('%[^a-zA-Z0-9()*-]%', ColumnName) > 0
8. CHARINDEXで「特定文字の有無」だけを調べる
PATINDEXは文字クラスやワイルドカードが使える一方、「特定のリテラル文字列が含まれるか」だけを調べたいならCHARINDEXの方がシンプルで、インデックスが効きやすいケースもあります。
-- "ABC" という文字列が含まれているか(位置を返す。0ならなし)
SELECT CHARINDEX('ABC', ColumnName) FROM SampleTable
-- 含まれている行だけ抽出
SELECT * FROM SampleTable WHERE CHARINDEX('@', ColumnName) > 0
LIKE '%ABC%'と似た結果になりますが、CHARINDEXは一致した開始位置を返すため、「何文字目に出現したか」をそのまま使いたい場合に向いています。「ワイルドカードや文字クラスが不要な単純な部分一致/位置取得」はCHARINDEX、「文字クラスや否定指定が必要な入力チェック」はLIKE/PATINDEX、と使い分けるとよいでしょう。
9. 注意点①:文字クラス内のハイフンの扱い
文字クラス[ ]の中でハイフン-は基本的に範囲指定として解釈されます。たとえば[a-z]は「aからzまで」を意味します。
そのため、次のように記述すると意図しない範囲指定になってしまうことがあります。
-- NG例:意図せず範囲指定になりうる
[a-zA-Z0-9()-*]
> ⚠️ よくある誤解として「バックスラッシュでエスケープすれば安全」という説明を見かけますが、SQL ServerのLIKEは既定ではを特別な文字として扱いません。`ESCAPE`句を明示的に指定しない限り`-`はただの「という文字」+「-という文字(または範囲指定の一部)」として解釈されるため、意図したエスケープにはなりません。
SQL Server的に安全なのは、ハイフンを文字クラスの先頭または末尾に置く方法です。先頭・末尾にあるハイフンは前後に範囲の相手がいないため、リテラルの「-」として扱われます。
-- OK:ハイフンを末尾に置く
[a-zA-Z0-9()*-]
-- OK:ハイフンを先頭に置く(否定の場合は ^ の直後)
[^-a-zA-Z0-9()*]
なお、Microsoft公式ドキュメントでは、文字クラス内で^・-・]をリテラルとして使いたい場合の表現として、二重の角かっこ([^]・[-]・[]]のような書き方)が紹介されています。ただ実務上は、上記のように位置をずらすだけで十分なケースが大半です。
10. 注意点②:全角文字と照合順序(COLLATE)の罠
[a-zA-Z0-9]のような範囲指定は、基本的には半角の英数字だけを意図したものです。
ABC → NG(全角英字)
123 → NG(全角数字)
- → NG(全角ハイフン)
…と思いきや、これはデータベース/列の照合順序(COLLATE)次第で結果が変わる点に注意が必要です。SQL Serverの既定の日本語照合順序(Japanese_CI_ASなど)は大文字・小文字だけでなく、設定によっては全角・半角の区別(_WS)やかなの区別(_KS)もあいまいに扱うため、環境によっては[a-z]が想定外の文字にもマッチしてしまうことがあります。
入力チェックのように厳密な半角/全角の区別が必要な場合は、COLLATE句でバイナリ照合順序を明示するのが安全です。
WHERE ColumnName NOT LIKE '%[^a-zA-Z0-9()*-]%' COLLATE Japanese_BIN2
Japanese_BIN2(またはご利用の言語に対応する_BIN2系)を指定すると、文字コード単位の厳密な比較になるため、全角・半角・大文字・小文字の揺れに振られにくくなります。マスタチェックや型式コードの厳密な検証では、こうした照合順序の固定もセットで検討してください。
11. 注意点③:SQL Server 2022以前には正規表現がない
よくある誤解ですが、SQL Server 2022以前のLIKEは正規表現ではありません。次のような書き方はエラーになります。
-- SQL Server 2022以前ではエラー
WHERE ColumnName LIKE '^[A-Za-z0-9]+$'
複雑な正規表現が必要な場合、SQL Server 2022以前では次のような手段を検討します。
- CLR関数(.NETの正規表現ライブラリをSQL Serverに登録する)
- アプリケーション側(C#、Java、PHPなど)でチェックしてからDBに渡す
- ETLツールでのデータ整形時にチェック
12. SQL Server 2025の正規表現関数チートシート
SQL Server 2025(互換性レベル170以上)では、Google製のRE2正規表現ライブラリをベースにした正規表現関数群がネイティブに使えるようになりました。
| 関数 | 用途 |
|---|---|
REGEXP_LIKE |
パターンに一致するかどうかを判定(LIKEの正規表現版) |
REGEXP_COUNT |
パターンに一致した回数を取得 |
REGEXP_INSTR |
パターンに一致した位置を取得(PATINDEXの正規表現版) |
REGEXP_REPLACE |
パターンに一致した部分を置換 |
REGEXP_SUBSTR |
パターンに一致した部分文字列を抜き出す |
REGEXP_MATCHES |
一致した部分文字列とキャプチャグループを表形式で返す |
REGEXP_SPLIT_TO_TABLE |
パターンを区切り文字として文字列を分割し、表形式で返す |
例えば、本記事のテーマである「英数字・ハイフン・カッコ・アスタリスクのみ許可」は、SQL Server 2025なら次の1行で書けます。
-- データベースの互換性レベルが170以上である必要があります
ALTER DATABASE [YourDatabase] SET COMPATIBILITY_LEVEL = 170;
SELECT *
FROM SampleTable
WHERE REGEXP_LIKE(ColumnName, '^[A-Za-z0-9()*-]*$')
CHECK制約に組み込んでおけば、INSERT/UPDATE時に自動でバリデーションすることもできます。
ALTER TABLE SampleTable
ADD CONSTRAINT CK_ColumnName_Format
CHECK (REGEXP_LIKE(ColumnName, '^[A-Za-z0-9()*-]*$'))
なお、REGEXP_LIKEを含む一部の正規表現関数はネイティブコンパイル ストアド プロシージャ内では使用できない、といった制約もあるため、本番導入前にMicrosoft Learnの最新ドキュメントで利用条件を確認することをおすすめします。
13. LIKE/PATINDEXと正規表現、どちらを使うべきか
| 観点 | LIKE / PATINDEX | REGEXP_LIKE等(SQL Server 2025+) |
|---|---|---|
| 対応バージョン | すべてのバージョン | SQL Server 2025以降・互換性レベル170以上 |
| 表現力 | 文字クラス・範囲・否定のみ。繰り返しやグループ化は不可 | 正規表現の繰り返し・グループ化・キャプチャが可能 |
| 学習コスト | 低い(SQLしか知らなくてもすぐ書ける) | 正規表現の知識が必要 |
| 複雑な形式チェック(メールアドレス、郵便番号など) | 複数条件の組み合わせが必要で読みづらくなりがち | 1パターンで簡潔に書ける |
「単純な許可文字チェック」程度であれば、互換性の高さからLIKE系を使い続けるのも十分実用的です。一方、メールアドレスや電話番号のような複雑なフォーマット検証が必要で、かつSQL Server 2025以降(またはAzure SQL)を使える環境であれば、正規表現関数への移行を検討する価値があります。
まとめ
- SQL Server 2022以前には標準の正規表現機能はないが、
LIKE・NOT LIKE・PATINDEX・CHARINDEXの組み合わせで多くの入力チェックを実現できる - 特に
NOT LIKE '%[^許可文字]%'の形は実務での頻出パターン - 文字クラス内のハイフンは「位置を先頭・末尾にする」のが安全(バックスラッシュでのエスケープは既定では効かない)
- 全角・半角の区別は照合順序(COLLATE)の影響を受けるため、厳密なチェックでは
_BIN2系の照合順序を明示する - SQL Server 2025(17.x)以降では
REGEXP_LIKEなどのネイティブ正規表現関数が使えるようになり、複雑なパターンマッチングが格段に書きやすくなった
環境のバージョンに応じて、本記事のパターン集とSQL Server 2025の正規表現関数を使い分けながら、データ品質向上やマスタチェックに活用してください。