正则表达式 第六篇:调用CLR函数执行正则查询
正则表达式在文本查询方面,不管是速度还是功能,都十分强大。虽然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)
参考文档:
Regular Expression Language - Quick Reference
正则表达式 第六篇:调用CLR函数执行正则查询的更多相关文章
- 第六篇 SQL Server安全执行上下文和代码签名
本篇文章是SQL Server安全系列的第六篇,详细内容请参考原文. SQL Server决定主体是否有必要的执行代码权限的根本途径是其执行上下文规则.这一切都可能复杂一个主体有执行代码的权限,但是却 ...
- 【译】第六篇 SQL Server安全执行上下文和代码签名
本篇文章是SQL Server安全系列的第六篇,详细内容请参考原文. SQL Server决定主体是否有必要的执行代码权限的根本途径是其执行上下文规则.这一切都可能复杂一个主体有执行代码的权限,但是却 ...
- 3D Slicer中文教程(六)—调用matlab函数(MatlabBridge使用方法)
1.安装MatlabBridge插件 (1)在工具栏找到Extension,点击进入Extension Manager (2)找到MatlabBridge,安装 2.配置MATLAB环境 (1)在模块 ...
- 第六篇:Python函数进阶篇
在了解完了 Python函数基础篇之后,本篇的存在其实是为了整合知识,由于该篇的知识是否杂乱,故大家可以通过点开点连接直接进入其详细介绍,该篇主要大致的介绍一下几个知识点: 一.Python的迭代器 ...
- 如何动态调用 C 函数
JSPatch 支持了动态调用 C 函数,无需在编译前桥接每个要调用的 C 函数,只需要在 JS 里调用前声明下这个函数,就可以直接调用: require('JPEngine').addExtensi ...
- 第30篇-main()方法的执行
在第7篇详细介绍过为Java方法创建的栈帧,如下图所示. 调用完generate_fixed_frame()函数后一些寄存器中保存的值如下: rbx:Method* ecx:invocation co ...
- UNIX环境编程学习笔记(22)——进程管理之system 函数执行命令行字符串
lienhua342014-10-15 ISO C 定义了 system 函数,用于在程序中执行一个命令字符串.其声明如下, #include <stdlib.h> int system( ...
- 小猪猪C++笔记基础篇(六)参数传递、函数重载、函数指针、调试帮助
小猪猪C++笔记基础篇(六) ————参数传递.函数重载.函数指针.调试帮助 关键词:参数传递.函数重载.函数指针.调试帮助 因为一些事情以及自己的懒惰,大概有一个星期没有继续读书了,已经不行了,赶紧 ...
- 【HANA系列】【第六篇】SAP HANA XS使用JavaScript(JS)调用存储过程(Procedures)
公众号:SAP Technical 本文作者:matinal 原文出处:http://www.cnblogs.com/SAPmatinal/ 原文链接:[HANA系列][第六篇]SAP HANA XS ...
随机推荐
- webpack 4 移除 CommonsChunkPlugin,取而代之的是两个新的配置项(optimization.splitChunks 和 optimization.runtimeChunk
默认方式 webpack模式模式现在已经做了一些通用性优化,适用于多数使用者. 需要注意的是:默认模式只影响按需(on-demand)加载的代码块(chunk),因为改变初始代码块会影响声明在HTML ...
- ES和zookeeper选取帮主之江湖秘闻
ES帮会 某日,ES帮会中决定选取老大统领帮会走向辉煌.大家七嘴八舌,讨论方案,场面一顿混乱.傻牛站起来大喊一声:谁比俺力气大,谁就当老大.(ES集群在启动时,选取集群master,按照nodeId进 ...
- 使用 Django 项目中的 ORM 编写伪造测试数据脚本
作者:HelloGitHub-追梦人物 文中所涉及的示例代码,已同步更新到 HelloGitHub-Team 仓库 为了防止博客首页展示的文章过多以及提升加载速度,可以对文章列表进行分页展示.不过这需 ...
- javascript核心基础总结
对<深入理解javascript原型和闭包系列>,<深入理解javascript系列>和<javascript深入系列>的学习总结 词法作用域 作用域就是,程序查找 ...
- 修改linux系统history命令的条数和格式
在一次测试环境遇到的情况,发现服务莫名其妙挂了,以为服务有bug,查了一下午,后来一个同事说,是我把服务关了啊.... 是可忍孰不可忍,原生的history命令,只能看到输入的命令历史,看不到什么时候 ...
- SpringBoot 2.0 开发案例之百倍级减肥瘦身之旅
前言 为了存我的小黄图,最近在做一款图床服务,集成了各种第三方云存储服务,目前正在内部测试阶段.项目是以Jar的形式运行在腾讯云上,不要问我为什么使用腾讯云了,因为阿里云老用户和狗不得入内. 问题凸显 ...
- 【Linux系列】Linux基础知识整理
Linux操作系统在服务器领域广泛的使用到,作为一个后台开发工程师很有必要了解Linux相关的知识. 本篇日志是我学习Linux过程中的简单记录和总结.本着"理论够用,实践为主"的 ...
- 百度地图Javascript API 调用示例
调用示例 !<!DOCTYPE html> <html> <head> <title>百度地图DEMO</title> </head& ...
- DP动态规划学习笔记
作为考察范围最广,考察次数最多的算法,当然要开一篇博客来复习啦. 子曰:温故而知新,可以为师矣 我复习DP时有一些自己对DP的理解,也就分享出来吧. ——正片开始—— 动态规划算法,即Dynamic ...
- C++学习笔记7_多态
1. 类与类之间的关系class A{ public: int a; void funcA() {}}包含: class B { public: void funcB(){} A a; }//如果类B ...