用程序集编写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程序,再部署 ...
随机推荐
- Linux mke2fs 硬盘格式化
[root@whp6 ~]# cat /etc/filesystems ext4 ext3 ext2 nodev proc nodev devpts iso9660 vfat hfs hfsplus ...
- java汉化
http://download.eclipse.org/technology/babel/babel_language_packs/R0.13.0/luna/luna.php _x86_64版本下载地 ...
- oracle函数--trunc
作用:截取 语法:trunc(date,[fmt]) TRUNC函数,ORA-01898 精度说明符过多 TRUNC(SYSDATE)即可默认当前日期(年月日),---写到这一步就好了 TRUNC ...
- Fitbit Flex 智能手环佩戴心得 主要说说过敏
参杂一篇杂文. 也是因为体重飙升,所以去年下半年的时候入手了一个Fitbit flex. 当时相比Jawbone up,nfc和ble的特性,以及防水性还是更吸引我一点.所以就入手了. 佩带了如此长的 ...
- 【转】XPath 示例
XPath 示例 其他版本 本主题回顾整个 XPath 参考中出现的语法示例. 所有示例均基于 XPath 语法的示例 XML 文件 (inventory.xml). 有关在测试文件中使用 X ...
- NET Core中实现一个Token base的身份认证
NET Core中实现一个Token base的身份认证 注:本文提到的代码示例下载地址> How to achieve a bearer token authentication and au ...
- python日期格式化与绘图
画一个量随着时间变化的曲线是经常会遇到的需求,比如画软件用户数的变化曲线.画随时间变化的曲线主要用到的函数是matplotlib.pyplot.plot_date(date,num).由于其第一个变量 ...
- ie 7/8不支持trim的属性的解决方案
if(!('trim' in String.prototype)){ String.prototype.trim = function(){ return this.replace(/^[\s\uFE ...
- DINIC网络流+当前弧优化
DINIC网络流+当前弧优化 const inf=; type rec=record s,e,w,next:longint; end; var b,bb,d,q,tb:..] of longint; ...
- DEDECMS之二 如何修改模板页
使用织梦系统最经常是为了仿站,那么模板应该怎么改? 这里主要谈谈关于比较常用的几个模板页 网站主页.列表页.内容页.栏目的调用 1.主页模板 常用组合方法:index.htm + head.htm + ...