正则表达式在文本查询方面,不管是速度还是功能,都十分强大。虽然SQL Server数据库可以执行模糊查询(像like子句)和全文查询(Fulltext search),但是这两个子句只能查询简单的模式,无法应对复杂的查询需求。这是因为SQL Server没有执行正则表达式的内置函数,无法直接执行正则查找。我们可以创建CLR标量函数,在函数中调用正则表达式,把CLR函数发布到SQL Server数据库中,这样,就可以通过TSQL脚本调用CLR函数来执行复杂的正则查询和匹配。

一,Regex类

Regex类用于表示一个正则表达式,执行匹配、替换和拆分操作,Regex类有五大方法:

  • IsMatch():是否匹配到正则
  • Match():返回正则的第一个匹配
  • Matches():返回正则的全部匹配
  • Replace():把匹配正则表达式的文本替换掉
  • Split():把输入文本拆分,拆分的边界是匹配正则表达式的文本

1,创建Regex 对象

创建Regex对象,并指定正则选项(忽略大小写):

Regex re = new Regex("(?<=\"UserID\":\").*?(?=\")", RegexOptions.IgnoreCase);
string mat = re.Match(input_text).Value;

也可以直接使用静态方法,直接获取到第一个匹配的值:

string mat = Regex.Match(input_txt,"(?<=\"UserID\":\").*?(?=\")", RegexOptions.IgnoreCase).Value;

2,查找匹配

按照正则来查看匹配的文本是正则表达式最常用的功能,

Regex re = new Regex("(?<=\"UserID\":\").*?(?=\")", RegexOptions.IgnoreCase);

MatchCollection mc = re.Matches(text_input);
foreach(Match mt in mc)
{
//mt.Value
}

二,创建CLR工程

我使用的IDE版本是VS2017 Enterprise,要创建CLR工程,首先需要创建SQL Server 类型的 Project。

1,新建CLR函数

在已创建的SQL Server Project中添加新项目(Add -> New Item),选项SQL CLR C# User Defined Function,这里把文件命名为UserDefinedFunctions.cs。

2,编写CLR代码

完整的CLR标量函数示例代码如下,Build 该文件,生成DLL文件,用该DLL文件创建程序集。

为了使用正则表达式,需要在文件中添加引用 : using System.Text.RegularExpressions;

using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
using System.Text;
using System.Text.RegularExpressions; public partial class UserDefinedFunctions
{
[Microsoft.SqlServer.Server.SqlFunction]
public static SqlString Match(string input, string pattern)
{
string str = Regex.Match(input, pattern, RegexOptions.IgnoreCase).Value;
return new SqlString (str);
} public static SqlBoolean IsMatch(string input, string pattern)
{
bool match = Regex.IsMatch(input, pattern, RegexOptions.IgnoreCase);
return new SqlBoolean(match);
} public static SqlString Matches(string input, string pattern)
{
MatchCollection mc = Regex.Matches(input, pattern, RegexOptions.IgnoreCase);
StringBuilder strList = new StringBuilder();
int idx = ;
foreach(Match m in mc)
{
strList.Append(string.Format("\"idx{0}\":\"{1}\",", idx, m.Value));
idx = idx + ;
}
return new SqlString(strList.ToString());
} public static SqlString SplitItem(string input, string separator, int idx)
{
string[] str = input.Split(new string[] { separator }, StringSplitOptions.RemoveEmptyEntries);
return str.Length> idx ? str[idx] : "";
}
public static string GetJsonItem(string input, string key)
{
string pattern = string.Format("(?<=\"{0}\":\").*?(?=\")", key);
return Regex.Match(input, pattern, RegexOptions.IgnoreCase).Value;
}
}

三,在SQL Server中创建CLR函数

要在SQL Server数据库中创建CLR函数,必须配置SQL Server的选项,然后使用DLL文件创建Assembly,并从Assembly创建SQL 函数。

1,配置SQL Server的选项

为了把CLR工程部署到SQL Server数据库中,需要配置数据库的高级选项,主要是禁用clr strict security 和启用clr enabled选项。

exec sp_configure 'show advanced options', 1
go
reconfigure;
go
exec sp_configure 'clr strict security', 0;
go
reconfigure;
go
exec sp_configure 'clr enabled', 1
go
reconfigure
go

2,创建程序集

引用CLR Project生成的DLL文件,用该DLL文件来创建SQL Server程序集:

CREATE ASSEMBLY [SQLServerDatabase]
FROM 'E:\clr_project_path.dll'
WITH PERMISSION_SET = SAFE
GO

3,从程序集中创建SQL函数

把SQL Server Database Project中的创建的函数,逐个创建为SQL函数。

CREATE FUNCTION [dbo].[Match](@input [nvarchar](max), @pattern [nvarchar](max))
RETURNS [nvarchar](max) WITH EXECUTE AS CALLER
AS
EXTERNAL NAME [SQLServerDatabase].[UserDefinedFunctions].[Match]
GO CREATE FUNCTION [dbo].[IsMatch](@input [nvarchar](max), @pattern [nvarchar](max))
RETURNS bit WITH EXECUTE AS CALLER
AS
EXTERNAL NAME [SQLServerDatabase].[UserDefinedFunctions].[IsMatch]
GO CREATE FUNCTION [dbo].[Matches](@input [nvarchar](max), @pattern [nvarchar](max))
RETURNS [nvarchar](max) WITH EXECUTE AS CALLER
AS
EXTERNAL NAME [SQLServerDatabase].[UserDefinedFunctions].[Matches]
GO CREATE FUNCTION [dbo].[SplitItem](@input [nvarchar](max), @separator [nvarchar](max), @idx int)
RETURNS [nvarchar](max) WITH EXECUTE AS CALLER
AS
EXTERNAL NAME [SQLServerDatabase].[UserDefinedFunctions].[SplitItem]
GO CREATE FUNCTION [dbo].[GetJsonItem](@input [nvarchar](max), @key [nvarchar](max))
RETURNS [nvarchar](max) WITH EXECUTE AS CALLER
AS
EXTERNAL NAME [SQLServerDatabase].[UserDefinedFunctions].[GetJsonItem]
GO

在SQL函数创建之后,就可以像调用普通函数那样来调用CLR函数。

update [dbo].[DimProductPath]
set ProductPath_ProductFamily=dbo.SplitItem(ProductPath,'/',0)
,ProductPath_ProductName=dbo.SplitItem(ProductPath,'/',1)
,ProductPath_ProductVersion=dbo.SplitItem(ProductPath,'/',2)
,ProductPath_SupportTopic=dbo.SplitItem(ProductPath,'/',3)
,ProductPath_SupportSubtopic=dbo.SplitItem(ProductPath,'/',4)

参考文档:

C#中正则表达式的使用

C# 正则表达式 菜鸟教程

Regular Expression Language - Quick Reference

正则表达式 第六篇:调用CLR函数执行正则查询的更多相关文章

  1. 第六篇 SQL Server安全执行上下文和代码签名

    本篇文章是SQL Server安全系列的第六篇,详细内容请参考原文. SQL Server决定主体是否有必要的执行代码权限的根本途径是其执行上下文规则.这一切都可能复杂一个主体有执行代码的权限,但是却 ...

  2. 【译】第六篇 SQL Server安全执行上下文和代码签名

    本篇文章是SQL Server安全系列的第六篇,详细内容请参考原文. SQL Server决定主体是否有必要的执行代码权限的根本途径是其执行上下文规则.这一切都可能复杂一个主体有执行代码的权限,但是却 ...

  3. 3D Slicer中文教程(六)—调用matlab函数(MatlabBridge使用方法)

    1.安装MatlabBridge插件 (1)在工具栏找到Extension,点击进入Extension Manager (2)找到MatlabBridge,安装 2.配置MATLAB环境 (1)在模块 ...

  4. 第六篇:Python函数进阶篇

    在了解完了 Python函数基础篇之后,本篇的存在其实是为了整合知识,由于该篇的知识是否杂乱,故大家可以通过点开点连接直接进入其详细介绍,该篇主要大致的介绍一下几个知识点:  一.Python的迭代器 ...

  5. 如何动态调用 C 函数

    JSPatch 支持了动态调用 C 函数,无需在编译前桥接每个要调用的 C 函数,只需要在 JS 里调用前声明下这个函数,就可以直接调用: require('JPEngine').addExtensi ...

  6. 第30篇-main()方法的执行

    在第7篇详细介绍过为Java方法创建的栈帧,如下图所示. 调用完generate_fixed_frame()函数后一些寄存器中保存的值如下: rbx:Method* ecx:invocation co ...

  7. UNIX环境编程学习笔记(22)——进程管理之system 函数执行命令行字符串

    lienhua342014-10-15 ISO C 定义了 system 函数,用于在程序中执行一个命令字符串.其声明如下, #include <stdlib.h> int system( ...

  8. 小猪猪C++笔记基础篇(六)参数传递、函数重载、函数指针、调试帮助

    小猪猪C++笔记基础篇(六) ————参数传递.函数重载.函数指针.调试帮助 关键词:参数传递.函数重载.函数指针.调试帮助 因为一些事情以及自己的懒惰,大概有一个星期没有继续读书了,已经不行了,赶紧 ...

  9. 【HANA系列】【第六篇】SAP HANA XS使用JavaScript(JS)调用存储过程(Procedures)

    公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[HANA系列][第六篇]SAP HANA XS ...

随机推荐

  1. konva canvas插件写雷达图示例

    最近,做了一个HTML5的项目,里面涉及到了雷达图效果,这里,我将react实战项目中,用到的雷达图单拎出来写一篇博客,供大家学习. 以下内容涉及的代码在我的gitlab仓库中:Konva canva ...

  2. 10 python学习笔记-操作数据库(十)

    在功能.接口测试中,常常需要通过数据库的操作,来准备数据.检测环境及核对功能.接口的数据库操作是否正确. 在自动化测试中,就需要我们用代码连接数据库自动完成数据准备. 环境检查及数据库断言的功能.数据 ...

  3. 简述RAID 0 和RAID 1 及RAID 5

    RAID 0 : 读.写速度提升 无容错能力 安全性差 最少磁盘数2.2+ 允许0块磁盘损坏 容量大 不建议企业使用 RAID 1 : 读速度提升 写速度略下降 有容错能力和安全性 允许有一块磁盘损坏 ...

  4. SpringBoot注入配置文件的3种方法

    方案1:@ConfigurationProperties+@Component 定义spring的一个实体bean装载配置文件信息,其它要使用配置信息是注入该实体bean /** * 将配置文件中配置 ...

  5. 爬虫之scrapy简单案例之猫眼

    在爬虫py文件下 class TopSpider(scrapy.Spider): name = 'top' allowed_domains = ['maoyan.com'] start_urls = ...

  6. Lucas的数论:杜教筛,莫比乌斯反演

    Description: 求$\sum\limits_{i=1}^{n} \sum\limits_{j=1}^{n} d(i \times j)$ $d(i)$表示$i$的约数个数和.$n \leq ...

  7. 小白学 Python(18):基础文件操作

    人生苦短,我选Python 前文传送门 小白学 Python(1):开篇 小白学 Python(2):基础数据类型(上) 小白学 Python(3):基础数据类型(下) 小白学 Python(4):变 ...

  8. CF600E Lomsat gelral——线段树合并/dsu on tree

    题目描述 一棵树有$n$个结点,每个结点都是一种颜色,每个颜色有一个编号,求树中每个子树的最多的颜色编号的和. 这个题意是真的窒息...具体意思是说,每个节点有一个颜色,你要找的是每个子树中颜色的众数 ...

  9. Wireshark嗅探抓取telnet明文账户密码

    0x00 Wireshark(前称Ethereal)是一个网络封包分析软件.网络封包分析软件的功能是撷取网络封包,并尽可能显示出最为详细的网络封包资料.Wireshark使用WinPCAP作为接口,直 ...

  10. LNMP+Redis架构部署

    工作机制 L(Linux)N(Nginx)M(Mysql)P(PHP)架构想必大家都知道,LNMP架构主要作用是让前端服务与后端存储以及后端的一下服务进行连接起来,来实现php程序的动态请求. 而今天 ...