正则表达式在文本查询方面,无论是速度仍是功能,都十分强大。虽然SQL Server数据库能够执行模糊查询(像like子句)和全文查询(Fulltext search),可是这两个子句只能查询简单的模式,没法应对复杂的查询需求。这是由于SQL Server没有执行正则表达式的内置函数,没法直接执行正则查找。咱们能够建立CLR标量函数,在函数中调用正则表达式,把CLR函数发布到SQL Server数据库中,这样,就能够经过TSQL脚本调用CLR函数来执行复杂的正则查询和匹配。html
Regex类用于表示一个正则表达式,执行匹配、替换和拆分操做,Regex类有五大方法:正则表达式
1,建立Regex 对象数据库
建立Regex对象,并指定正则选项(忽略大小写):express
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,查找匹配ui
按照正则来查看匹配的文本是正则表达式最经常使用的功能,spa
Regex re = new Regex("(?<=\"UserID\":\").*?(?=\")", RegexOptions.IgnoreCase); MatchCollection mc = re.Matches(text_input); foreach(Match mt in mc) { //mt.Value }
我使用的IDE版本是VS2017 Enterprise,要建立CLR工程,首先须要建立SQL Server 类型的 Project。code
1,新建CLR函数orm
在已建立的SQL Server Project中添加新项目(Add -> New Item),选项SQL CLR C# User Defined Function,这里把文件命名为UserDefinedFunctions.cs。htm
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 = 0; foreach(Match m in mc) { strList.Append(string.Format("\"idx{0}\":\"{1}\",", idx, m.Value)); idx = idx + 1; } 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的选项,而后使用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)
参考文档: