T-SQL 正则表达式(CLR 实现)
正则表达式在处理字符串方面有其特殊的优势,但是T-SQL至今没有支持(遗憾)。不过可以通过CLR函数"曲线救国"。
闲话不说,开工(需要SQLServer2005及以上版本)。
编写程序集(ClrRegExClass.cs)
usingSystem;
usingSystem.Data;
usingSystem.Data.SqlClient;
usingSystem.Data.SqlTypes;
usingMicrosoft.SqlServer.Server;
usingSystem.Text.RegularExpressions;
publicpartialclassRegExp
{
//验证字符串中是否包含与指定的匹配模式一致的字符串
[SqlFunction(IsDeterministic=true,IsPrecise=true)]
publicstaticSqlBooleanRegExIsMatch(SqlStringexpression,SqlStringpattern)
{
returnnewSqlBoolean(Regex.IsMatch(expression.ToString(),pattern.ToString()));
}
//替换字符串中与指定的匹配模式一致的字符串
[SqlFunction(IsDeterministic=true,IsPrecise=true)]
publicstaticSqlStringRegExReplace(SqlStringexpression,SqlStringpattern,SqlStringreplacement)
{
returnnewSqlString(Regex.Replace(expression.ToString(),pattern.ToString(),replacement.ToString()));
}
//提取字符串中与指定的匹配模式一致的字符串
[SqlFunction(IsDeterministic=true,IsPrecise=true)]
publicstaticSqlStringRegExSubstring(SqlStringexpression,SqlStringpattern,SqlInt32position,SqlInt32occurrence)
{
if(expression.ToString().Length正则表达式;
//@position为字符串开始的位置;@occurrence为与指定的匹配模式一致的字符串出现的次数
ifobject_id('dbo.regex_ismatch','FS')isnotnull
dropfunctiondbo.regex_ismatch;
go
createfunctiondbo.regex_ismatch
(@expressionnvarchar(max),@patternnvarchar(max))
returnsbitwithreturnsnullonnullinput
asexternalnameRegExp.RegExp.RegExIsMatch;
go
--验证字符串是否以[server]开头
--selectdbo.regex_ismatch('[server].[database].[schema].[object]','^\[server\]');
ifobject_id('dbo.regex_replace','FS')isnotnull
dropfunctiondbo.regex_replace;
go
createfunctiondbo.regex_replace
(@expressionnvarchar(max),@patternnvarchar(max),@replacementnvarchar(max))
returnsnvarchar(max)withreturnsnullonnullinput
asexternalnameRegExp.RegExp.RegExReplace;
go
--将字符串中[...]替换为"..."
--selectdbo.regex_replace('[server].[database].[schema].[object]','\[([\w]*)\]','"$1"');
ifobject_id('dbo.regex_substring','FS')isnotnull
dropfunctiondbo.regex_substring;
go
createfunctiondbo.regex_substring
(@expressionnvarchar(max),@patternnvarchar(max),@positionint,@occurrenceint)
returnsnvarchar(max)withreturnsnullonnullinput
asexternalnameRegExp.RegExp.RegExSubstring;
go
--提取字符串中与[...]模式匹配的第二次出现的字符串
--selectdbo.regex_substring('[server].[database].[schema].[object]','\[\w*\]',1,2);ifobject_id('dbo.regex_count','FS')isnotnulldropfunctiondbo.regex_count;gocreatefunctiondbo.regex_count(@expressionnvarchar(max),@patternnvarchar(max),@positionint)returnsintwithreturnsnullonnullinputasexternalnameRegExp.RegExp.RegExCount;go--计算字符串中与[...]模式匹配的字符串的数目
--selectdbo.regex_count('[server].[database].[schema].[object]','\[\w*\]',1);
ifobject_id('dbo.regex_index','FS')isnotnull
dropfunctiondbo.regex_index;
go
createfunctiondbo.regex_index
(@expressionnvarchar(max),@patternnvarchar(max),@positionint,@occurrenceint)
returnsintwithreturnsnullonnullinput
asexternalnameRegExp.RegExp.RegExIndex;
go
--查询字符串中与[...]模式匹配的第二次出现的字符串开始的位置
--selectdbo.regex_index('[server].[database].[schema].[object]','\[\w*\]',1,2);
完成。
遗憾的是,这些T-SQL函数不能像SQLServer内置的系统函数一样在任何数据库下直接通过函数名调用。
可选的方法,将这些函数存储在MASTER数据库中,再在用户数据库下创建这些函数的同以词以方便调用(有点麻烦)。