2010年4月21日水曜日

SQL-Server 2008 Expressで、正規表現で文字列のパターン判定をする関数をSQLCLRで作ってみる



今回の記事は、SQL-Server 2008 Expressにおいて、正規表現を使って文字列のパターン判定をする関数をSQLCLRで作ってみます。

SQL-Serverにおいて文字列のパターン判定を行う場合は、「like」を使うのですが、これはごく簡単なパターンしか扱えない上に、同時に複数のパターンを記述すると、SQL文が極めて複雑になりがちで、結構涙目になる事って多いんじゃないかと思います。

そこで、SQLCLR_Regex()という関数を作り、正規表現そのものをダイレクトで使えるようにしようと思います。コードは極めて簡単で、正規表現を実現するクラス「Regex」を利用するだけ。
SQLCLRの恩恵ですね。
ヒットすればbit型で1、しなければ0が返るようにします。これで判定可能です。

たとえば、こんな感じです。
「日時の書式で、日.時間:分という形になってるかどうかチェック。ただし、日、時間、分の要素はそれぞれ数値1桁から4桁まであること」
こんなのはlikeではとても書ききれませんが、正規表現ならば、「^\d{1,4}\.\d{1,4}:\d{1,4}$」というように書く事が可能です。(\は¥記号)

SELECT dbo.SQLCLR_Regex('1.08:15','^\d{1,4}\.\d{1,4}:\d{1,4}$')
これはOKなので1が返ります。

SQLCLRの登録については過去の記事をご参考になさって下さい。

■コード■
(無償版のVisual C# 2008でプログラムを書けます)
(ブログではインデントが消えております)


//------------------------------------
//正規表現
//------------------------------------
//using System.Text.RegularExpressions;を記述して下さい。
[Microsoft.SqlServer.Server.SqlFunction]
public static SqlBoolean SQLCLR_Regex(
SqlString p_value,
SqlString p_pat
)
{
//正規表現
Regex obj_rx;
//結果格納エリア
SqlBoolean Qbol_result = true;

try
{
obj_rx = new Regex((string)p_pat);
if (!(obj_rx.IsMatch((string)p_value)))
{
Qbol_result = false;
}
}
catch (System.Exception obj_err)
{ //例外が発生したらSQL-Serverに投げつけて強制停止する。
throw obj_err;
}

return Qbol_result;
}


■SQL-Server 2008 Express側の関数インターフェース記述■
(環境はご自分に合わせて読み替えて下さいませ)

-- *******************************************************
-- SQLCLRの関数インターフェース
-- *******************************************************
-- ----------------------------------------------
-- 正規表現による条件判定
-- (パラメータ説明)
-- @p_value:判定したい文字列

-- @p_pat:正規表現パターン
-- ----------------------------------------------
create function SQLCLR_Regex(
@p_value nvarchar(max),
@p_pat nvarchar(max)
) RETURNS bit
AS EXTERNAL NAME ASSEMBLY_SQLCLR.CLS_SQLCLR.SQLCLR_Regex;

ちなみに、マイクロソフトによると、Regexの読みは「レジェックス」か「レグエクス」どっちでも好きな方で良いとのことです。