正则表达式非常好,但在数据库中就是没有,但可以通过程序集方式扩展

先编写一个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,)
});
//开始填充
SqlContext.Pipe.SendResultsStart(dataRecord); MatchCollection mc;
Regex r = new Regex(patten);
mc = r.Matches(input);
for (int i = ; i < mc.Count; i++)
{
//SqlDataRecord.SetString类似DataRow的功能,像Table中填充值
dataRecord.SetInt32(, i);
dataRecord.SetInt32(, mc[i].Index);
dataRecord.SetString(, 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表值函数:把正则表达式引入数据库中的更多相关文章

  1. PCB MS SQL表值函数与CLR 表值函数 (例:字符串分割转表)

    将字符串分割为表表经常用到,这里 SQL表值函数与CLR  表值函数,两种实现方法例出来如下: SELECT * FROM FP_EMSDB_PUB.dbo.SqlSplit('/','1oz/1.5 ...

  2. 给定一个英文字符串,请编写一个PHP函数找出这个字符串中首先出现三次的那个英文字符(需要区分大小写),并返回

    给定一个英文字符串,请编写一个PHP函数找出这个字符串中首先出现三次的那个英文字符(需要区分大小写),并返回 //统计字符串中出现的字符的出现次数 public function strNum(){ ...

  3. 转载——CLR标量函数、表值函数和聚合函数(UDA)

    本节主要介绍使用CLR创建标量函数,表值函数和聚合函数. 所谓标量函数指的就是此函数只返回一个值.表值函数返回值是一个表.聚合函数是在select语句中使用的,用来聚合一个结果集,类似于Sum()或是 ...

  4. 【SQL】CLR聚合函数什么鬼

    之前写过一个合并字符串的CLR聚合函数,基本是照抄MS的示例,外加了一些处理,已经投入使用很长时间,没什么问题也就没怎么研究,近日想改造一下,遇到一些问题,遂捣鼓一番,有些心得,记录如下. 一.杂项 ...

  5. SQL Server中的CLR编程——用.NET为SQL Server编写存储过程和函数

    原文:SQL Server中的CLR编程--用.NET为SQL Server编写存储过程和函数 很早就知道可以用.NET为SQL Server2005及以上版本编写存储过程.触发器和存储过程的,不过之 ...

  6. PCB MS SQL 标量函数与表值函数(CLR) 实现文件与目录操作

    一.C#写SQL SERVER(CLR)实现文件操作 标量函数: 文件移动 ,复制,检测文件存在,写入新文件文本,读取文本,创建目录,删除目录,检测目录是否存在 /// <summary> ...

  7. Sql CLR创建一个简单的表值函数

    1.创建面目: 2. 添加函数代码: using System; using System.Data.Sql; using Microsoft.SqlServer.Server; using Syst ...

  8. C#编写CLR函数

    本案例在VS2017环境中开发: 1.新建项目,“数据库项目”,添加 UserDefinedFunctions.cs类文件,代码如下: using System; using System.Data; ...

  9. 编写CLR存储过程中使用SqlDataRecord

    温习一下这些天学习的CLR编程,存储过程,函数. 编写CLR的存储过程,运行起来的效率,果然比普通的SQL语句,存储过程或是函数均高. 以后专案需求,或是执行效率较高的SQL,得写成CLR程序,再部署 ...

随机推荐

  1. Linux mke2fs 硬盘格式化

    [root@whp6 ~]# cat /etc/filesystems ext4 ext3 ext2 nodev proc nodev devpts iso9660 vfat hfs hfsplus ...

  2. java汉化

    http://download.eclipse.org/technology/babel/babel_language_packs/R0.13.0/luna/luna.php _x86_64版本下载地 ...

  3. oracle函数--trunc

    作用:截取 语法:trunc(date,[fmt])   TRUNC函数,ORA-01898 精度说明符过多 TRUNC(SYSDATE)即可默认当前日期(年月日),---写到这一步就好了 TRUNC ...

  4. Fitbit Flex 智能手环佩戴心得 主要说说过敏

    参杂一篇杂文. 也是因为体重飙升,所以去年下半年的时候入手了一个Fitbit flex. 当时相比Jawbone up,nfc和ble的特性,以及防水性还是更吸引我一点.所以就入手了. 佩带了如此长的 ...

  5. 【转】XPath 示例

    XPath 示例   其他版本   本主题回顾整个 XPath 参考中出现的语法示例. 所有示例均基于 XPath 语法的示例 XML 文件 (inventory.xml). 有关在测试文件中使用 X ...

  6. NET Core中实现一个Token base的身份认证

    NET Core中实现一个Token base的身份认证 注:本文提到的代码示例下载地址> How to achieve a bearer token authentication and au ...

  7. python日期格式化与绘图

    画一个量随着时间变化的曲线是经常会遇到的需求,比如画软件用户数的变化曲线.画随时间变化的曲线主要用到的函数是matplotlib.pyplot.plot_date(date,num).由于其第一个变量 ...

  8. ie 7/8不支持trim的属性的解决方案

    if(!('trim' in String.prototype)){ String.prototype.trim = function(){ return this.replace(/^[\s\uFE ...

  9. DINIC网络流+当前弧优化

    DINIC网络流+当前弧优化 const inf=; type rec=record s,e,w,next:longint; end; var b,bb,d,q,tb:..] of longint; ...

  10. DEDECMS之二 如何修改模板页

    使用织梦系统最经常是为了仿站,那么模板应该怎么改? 这里主要谈谈关于比较常用的几个模板页 网站主页.列表页.内容页.栏目的调用 1.主页模板 常用组合方法:index.htm + head.htm + ...