正则表达式在文本查询方面,不管是速度还是功能,都十分强大。虽然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. 雷子聊并发编程(001):基础知识之串行&并行&并发

    前言 编写正确的程序很难,而编写正确的并发程序则难上加难.与串行程序相比,在并发程序中存在更多容易出错的地方.那么,为什么还要编写并发程序?原因很简单,能充分发挥与利用多处理器系统的强大计算能力. 在 ...

  2. codeforce -14A A. Letter

    A. Letter time limit per test 1 second memory limit per test 64 megabytes input standard input outpu ...

  3. 怎样通过excel录入来批量造数据

    背景: 自动化测试除了验证系统功能外,还能够为测试人员根据测试要求造数据实现测试需要!但是一般的自动化测试,都是在编写脚本的时候,写死在程序里的.所以本文是为了在满足系统操作流程的基础上,根据测试的要 ...

  4. js 的隐式转换与显式转换

    隐式转换   1.undefined与null相等,但不恒等(===) 2.一个是number一个是string时,会尝试将string转换为number 3.隐式转换将boolean转换为numbe ...

  5. Windows许可证即将过期怎么办?

    最近在使用电脑的时候,一开机就会弹窗出现:Windows 许可证即将过期.我勒个去,windows还会过期啊. 我搜遍全网,发现了一个很棒的 Windows10 永久激活的工具,而且没有广告什么乱七八 ...

  6. 爬虫基本库的使用---requests库

    使用requests---实现Cookies.登录验证.代理设置等操作 处理网页验证和Cookies时,需要写Opener和Handler来处理,为了更方便地实现这些操作,就有了更强大的库reques ...

  7. Android Studio接谷歌原生登录

    目录 前言 AndroidStudio server_client_id @ 前言 准备 近日,公司要求上线海外市场,需要接入海外SDK,首先上架的是GooglePlay,需要先接入GooglePla ...

  8. Java Part 001( 01_01_Java概述 )

    Java作为编程语言, 甚至超出了语言的范畴, 成为一种开发平台, 一种开发规范. Java语言相关的JavaEE规范里, 包含了时下最流行的各种软件工程理念, 学习Java相当于系统的学习了软件开发 ...

  9. 爬虫学习--Urllib库基本使用 Day1

    一.Urllib库详解 1.什么是Urllib Python内置的HTTP请求库 urllib.request    请求模块(模拟实现传入网址访问) urllib.error             ...

  10. PHP关于access_token失效问题

    PHP关于access_token失效问题 有时候PHP设置了缓存 明明就是没有过期 但却提示失效这情况一般就是1 多个appid和secrete 生成的access_token互相覆盖了 所以 这种 ...