正則表達式學習之調用CLR函數執行正則查詢

正則表達式在文本查詢方面,不管是速度還是功能,都十分強大。雖然SQL Server數據庫可以執行模糊查詢(像like子句)和全文查詢(Fulltext search),但是這兩個子句只能查詢簡單的模式,無法應對複雜的查詢需求。

在之前的公司,我們前端使用webpack構建項目,項目構建完成後,我們會使用ftp或linux的一些命令工具上傳我們的文件到服務器上,這種方式雖然是可以,但是最近面試的時候,人家會問我前端如何部署項目,我就說我們公司目前是這樣操作的,最後人家會感覺很low,最後總之總之沒有面試上。因此今天來給大家介紹下使用Jenkins基於github來實現前端自動化集成打包部署前端資源文件。

Jenkins基本介紹: Jenkins是一個開源軟件項目,它是基於java開發的一種持續集成工具,它用於監控持續重複的工作。
它最大的優點是:在開發環境或測試環境代碼部署都不需要運維介入,而是相關的開發人員,測試人員登錄jenkins構建需要部署的tag或分支代碼即可。整個過程不需要運維參與。因此我們現在想使用jenkins的話,我們首先需要安裝java開發環境。

這是因爲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 = 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數據庫中創建CLR函數,必須配置SQL Server的選項,然後使用DLL文件創建Assembly,並從Assembly創建SQL 函數。

實現的目標是:我們的本地項目發起一個git提交後,剩下的單元測試, 打包構建,代碼部署,郵件提醒等,我們會全部自動化完成部署。

3.1. 準備

首先我們隨便準備一個項目(我這邊是使用webpack搭建的vue項目了),在git倉庫中新建一個項目,然後把該本地項目提交到github上去。

比如我這邊項目如下所示:

1,配置SQL Server的選項

爲了把CLR工程部署到SQL Server數據庫中,需要配置數據庫的高級選項,主要是禁用clr strict security 和啓用clr enabled選項。

$ sudo vim /var/lib/jenkins/secrets/initialAdminPassword

然後複製密碼後填寫上去,繼續執行下面的步驟即可。

這個過程可能會加載很慢,我們稍等一下後,我們按照默認配置安裝插件即可,如下所示:

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)

$ wget -q -O - https://pkg.jenkins.io/debian/jenkins.io.key | sudo apt-key add -
sudo sh -c 'echo deb http://pkg.jenkins.io/debian-stable binary/ > /etc/apt/sources.list.d/jenkins.list'

$ sudo apt-get update

$ sudo apt-get install jenkins

我們現在要實現這麼一個功能,當我們在本地項目往github遠程倉庫push我們的代碼的時候,jenkins就能知道我們提交了代碼,要實現這麼一個功能的基本原理是:在遠程倉庫上需要配置一個Jenkins服務的接口地址,當本地向遠程倉庫發起push時候,遠程倉庫會向配置的Jenkins服務器的接口地址發起一個帶參數的請求,當jenkins收到後開始工作。

配置步驟如下:

Github配置

1) 在Github上獲取訪問token的值,需要一個對項目有寫權限的賬戶。

如果要實現自動構建的話,Jenkins需要獲得遠程代碼倉庫Github的讀取權。

點擊右上角的 Github --> setting --> Developer settting --> Personal access tokens -> 點擊Generate new token 填寫如下所示的內容:

發佈了242 篇原創文章 · 獲贊 1544 · 訪問量 63萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章