用程序集编写clr表值函数:把正则表达式引入数据库中
正则表达式非常好,但在数据库中就是没有,但可以通过程序集方式扩展
先编写一个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表值函数:把正则表达式引入数据库中的更多相关文章
- PCB MS SQL表值函数与CLR 表值函数 (例:字符串分割转表)
将字符串分割为表表经常用到,这里 SQL表值函数与CLR 表值函数,两种实现方法例出来如下: SELECT * FROM FP_EMSDB_PUB.dbo.SqlSplit('/','1oz/1.5 ...
- 给定一个英文字符串,请编写一个PHP函数找出这个字符串中首先出现三次的那个英文字符(需要区分大小写),并返回
给定一个英文字符串,请编写一个PHP函数找出这个字符串中首先出现三次的那个英文字符(需要区分大小写),并返回 //统计字符串中出现的字符的出现次数 public function strNum(){ ...
- 转载——CLR标量函数、表值函数和聚合函数(UDA)
本节主要介绍使用CLR创建标量函数,表值函数和聚合函数. 所谓标量函数指的就是此函数只返回一个值.表值函数返回值是一个表.聚合函数是在select语句中使用的,用来聚合一个结果集,类似于Sum()或是 ...
- 【SQL】CLR聚合函数什么鬼
之前写过一个合并字符串的CLR聚合函数,基本是照抄MS的示例,外加了一些处理,已经投入使用很长时间,没什么问题也就没怎么研究,近日想改造一下,遇到一些问题,遂捣鼓一番,有些心得,记录如下. 一.杂项 ...
- SQL Server中的CLR编程——用.NET为SQL Server编写存储过程和函数
原文:SQL Server中的CLR编程--用.NET为SQL Server编写存储过程和函数 很早就知道可以用.NET为SQL Server2005及以上版本编写存储过程.触发器和存储过程的,不过之 ...
- PCB MS SQL 标量函数与表值函数(CLR) 实现文件与目录操作
一.C#写SQL SERVER(CLR)实现文件操作 标量函数: 文件移动 ,复制,检测文件存在,写入新文件文本,读取文本,创建目录,删除目录,检测目录是否存在 /// <summary> ...
- Sql CLR创建一个简单的表值函数
1.创建面目: 2. 添加函数代码: using System; using System.Data.Sql; using Microsoft.SqlServer.Server; using Syst ...
- C#编写CLR函数
本案例在VS2017环境中开发: 1.新建项目,“数据库项目”,添加 UserDefinedFunctions.cs类文件,代码如下: using System; using System.Data; ...
- 编写CLR存储过程中使用SqlDataRecord
温习一下这些天学习的CLR编程,存储过程,函数. 编写CLR的存储过程,运行起来的效率,果然比普通的SQL语句,存储过程或是函数均高. 以后专案需求,或是执行效率较高的SQL,得写成CLR程序,再部署 ...
随机推荐
- x01.Game.CubeRun: 风一样的女子
1.题解 小孩学英语比较有意思,Monkey three => 猴三,风一样的女子 => 风 Girl.诸如此类不是重点,重点是一花一世界,一草一天堂.花花草草,纷纷扰扰.大千世界,当别具 ...
- 注意Android里TextView控件的一个小坑,用android:theme来设置样式时动态载入的layout会丢失该样式
注意Android里TextView控件的一个小坑,用android:theme来设置样式时动态载入的layout会丢失该样式 这个坑,必须要注意呀, 比如在用ListView的时候,如果在List_ ...
- C语言中链表怎么删除结点?
第一个方法: /*根据姓名删除链表的中的学生记录*/ void deleteByName(struct STUDENT * head) { struct STUDENT *p,*q; ]; if(he ...
- centos---无线上网的电脑所安装的虚拟机网络设置
1.共享设置 找到本地的无线网卡,右键---属性---共享,设置如下 2.修改VMware Network Adapter VMnet1 选中VMware Network Adapter VMnet1 ...
- Redhat Linux 修改主机名(HOSTNAME)
hostname #查看当前主机的主机名hostname NEWHOSTNAME #临时修改当前主机名 修改主机名vi /etc/sysconfig/network #通过配置文件修改主机名NETWO ...
- python paramiko
paramiko 遵循SSH2协议,支持以加密和认证的方式,进行远程服务器的连接,可以实现远程文件的上传,下载或通过ssh远程执行命令. 项目地址:https://github.com/paramik ...
- MMORPG大型游戏设计与开发(构架)
游戏整体是以经典的武侠世界/天龙八部作为基本的一种设计模式,大致分为以下几个部分. 游戏的简单的一次处理流程如下,不过有些凌乱,还有待完善. 程序设计方面,服务器基本上分为数据处理.日志.网络等模块, ...
- Book LIst
Go ahead. Linux APUE Linux Kernel Development 鸟哥的linux私房菜 基础篇 鸟哥的linux私房菜 服务器篇 Network Computer Netw ...
- cuda多线程间通信
#include "cuda_runtime.h" #include "device_launch_parameters.h" #include <std ...
- BZOJ1085: [SCOI2005]骑士精神 [迭代加深搜索 IDA*]
1085: [SCOI2005]骑士精神 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 1800 Solved: 984[Submit][Statu ...