正则表达式非常好,但在数据库中就是没有,但可以通过程序集方式扩展 先编写一个dll,标量函数很好写,表值函数麻烦一点 下面是C#代码 using System; using System.Data; using System.Data.SqlClient; using System.Data.SqlTypes; using Microsoft.SqlServ
正则表达式非常好,但在数据库中就是没有,但可以通过程序集方式扩展
先编写一个dll,标量函数很好写,表值函数麻烦一点
下面是C#代码
using System; using System.Data; using System.Data.SqlClient; using System.Data.SqlTypes; using Microsoft.SqlServer.Server; using System.Text.RegularExpressions; using System.Collections; public partial class RegExpFunctions {
[SqlFunction(
DataAccess = DataAccessKind.Read,
FillRowMethodName = "MatchsFun_FillRow",
TableDefinition = "pos int,match NVARCHAR(500)")]
public static IEnumerable MatchsFun(string input, string patten)
{
MatchCollection mc;
Regex r = new Regex(patten);
mc = r.Matches(input);
return mc;
}
public static void MatchsFun_FillRow(object mc,out int pos,out SqlString sqlmatch)
{
Match it = (Match)mc;
pos = it.Index;
sqlmatch = it.Value;
}
};
程序集名称是RegulerExp2
代码中有几点解释一下:
(1)表值函数必须是IEnumerable,简单讲是必须有这个接口的类,MatchCollection就具有这个接口;
(2)必须提供一个回调函数,在函数属性FillRowMethodName = "MatchsFun_FillRow"中指明,这个函数负责填充数据,
public static void MatchsFun_FillRow(object mc,out int pos,out SqlString sqlmatch)
{
Match it = (Match)mc;
pos = it.Index;
sqlmatch = it.Value;
}
这里的object mc是什么呢?
我们可以想象一下遍历
foreach (Match it in mc)
{
}
这里的object mc就是foreach里的Match it。
然后数据库把out int pos,out SqlString sqlmatch这两个量取出去放进表里。
下一步是添加程序集
第一步是把数据库的clr打开,不细说,自己网上查
第二步添加程序集
第三步,写一个数据库表值函数包装
create FUNCTION [ dbo ] . [ MatchList ] ( @input [ nvarchar ] ( 1000 ), @patten [ nvarchar ] ( 1000 )) RETURNS TABLE ( pos int , [ match ] [ nvarchar ] ( 500 ) NULL ) WITH EXECUTE AS CALLER AS EXTERNAL NAME [ RegulerExp2 ] . [ RegExpFunctions ] . [ MatchsFun ]
可以了。
前面写了一个小示例,大家好像没兴趣,写一个实用点的例子吧。数据库中没有split函数,用正则表达式就很容易了
select match from dbo.MatchList( ' 1,2,4,12,24,41 ' , ' (? ' )
结果为
如果以一个存储过程方式
C#代码为
[Microsoft.SqlServer.Server.SqlProcedure] public static void Matches( string input, string patten) { // 像构造Table一样来构造SqlDataRecord,其中SqlMetaData类似DataColumn SqlDataRecord dataRecord = new SqlDataRecord( new SqlMetaData[] { new SqlMetaData( " ID " , SqlDbType.Int), new SqlMetaData( " index " , SqlDbType.Int), new SqlMetaData( " match " , SqlDbType.NVarChar, 100 ) }); // 开始填充 SqlContext.Pipe.SendResultsStart(dataRecord); MatchCollection mc; Regex r = new Regex(patten); mc = r.Matches(input); for ( int i = 0 ; i ) { // SqlDataRecord.SetString类似DataRow的功能,像Table中填充值 dataRecord.SetInt32( 0 , i); dataRecord.SetInt32( 1 , mc[i].Index); dataRecord.SetString( 2 , mc[i].Value); // 通过SendResultsRow把数据填充到Table,相关于Table.Rows.Add(DataRow); SqlContext.Pipe.SendResultsRow(dataRecord); } // 填充结束,返回结果集 SqlContext.Pipe.SendResultsEnd(); }
数据库端写一个存储过程包装
CREATE PROCEDURE [ dbo ] . [ Macths ] @input [ nvarchar ] ( 1000 ), @patten [ nvarchar ] ( 1000 ) WITH EXECUTE AS CALLER AS EXTERNAL NAME [ RegulerExp ] . [ RegulerExp ] . [ Matches ]
别的一样
运行
exec dbo.Macths ' 1,2,4,12,24,41 ' , ' (? '
结果为
其他标量函数很简单,自己百度,类似
查看更多关于用程序集编写clr表值函数:把正则表达式引入数据库中的详细内容...