正则表达式在文本查询方面,不管是速度还是功能,都十分强大。虽然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. The usage of Markdown---引用

    目录 1. 序言 2. 引用与嵌套引用 3. 列表中的引用 更新时间:209.09.14 1. 序言   在本篇,我们来仔细谈一下Markdown的引用. 2. 引用与嵌套引用   在Markdown ...

  2. 《TypeScript入门教程》笔记

    基础 原始数据类型 布尔值 let isDone: boolean = false; 数值 let decLiteral: number = 6; 字符串 let myName: string = ' ...

  3. 数据类型(三) + 流程控制(一) day05

    目录 昨日回顾 (三) 花式赋值 链式赋值 交叉赋值 (四) 列表list (五) 字典dict (六) 布尔值 (七) 解压缩 (八) python与用户交互的方式 (九) 三种格式化输出的方式 f ...

  4. django-模板之comment标签(六)

    index.html <!DOCTYPE html> <html lang="en"> <head> <meta charset=&quo ...

  5. iOS 原生库对 https 的处理

    转载自:swift cafe 使用 NSURLSession NSURLSession 是 iOS 原生提供的网络处理库.它提供了丰富的接口以及配置选项,满足我们平时网络处理的大部分需求,同时它也支持 ...

  6. Exceptionless—本地部署

    参考:https://blog.csdn.net/shiyaru1314/article/details/76176236 自己采坑: ES 1.7.5版本不好使.使用最新版本6.X以上版本也不行 用 ...

  7. 编译原理实验 NFA子集法构造DFA,DFA的识别 c++11实现

    实验内容 将非确定性有限状态自动机通过子集法构造确定性有限状态自动机. 实验步骤 1,读入NFA状态.注意最后需要设置终止状态. 2,初始态取空,构造DFA的l0状态,将l0加入未标记状态队列que ...

  8. 知否知否,VS Code 不止开源

    VS Code, 昨夜始于“开源”,如今“开源”深处渡. 读者看到这句话,也许会有疑惑,为什么两个“开源”都加上了双引号? 其实是笔者有意为之,因为这个两个“开源”的意义有着很大的差别,第一个“开源” ...

  9. 在VMware下的Linux中的RAID10校验位算法下的磁盘管理

    988年由加利福尼亚大学伯克利分校发表的文章首次提到并定义了RAID,当今CPU性能每年可提升30%-50%但硬盘仅提升7%,渐渐的已经成为计算机整体性能的瓶颈,并且为了避免硬盘的突然损坏导致数据丢失 ...

  10. Web for pentester_writeup之XML attacks篇

    Web for pentester_writeup之XML attacks篇 XML attacks(XML攻击) Example 1 - XML外部实体注入(XXE) Payload http:// ...