如何在SQL Server中調用類庫來使用正則表達式?

SQL 腳本語言 技術 IT豆豆 2017-05-16

前言

通常,我們要在SQL Server的T-SQL查詢語句中使用正則表達式是很困難的。但正則表達式在進行字符串的匹配和查詢中確實又給我們帶來了很大的方便,往往能達到 Like 語句所不能達到的效果。那有沒有辦法,讓我們在 SQL 語句中能用上正則表達式呢?答案是肯定的,我們可以通過 MS SQL Server CLR 集成來使用正則表達式。

本文將介紹如何使 Like 語句支持正則表達式的 T-SQL 子句的創建和擴展。為了演示,還創建了一個文本解析器,通過給定的正則表達式,從文本中提取期望的查詢結果。此外,還有介紹了在 MS SQL Server Integration 下,通過 .Net Framework Common Language Runtime(CLR)編譯數據庫對象的類庫。

如何在SQL Server中調用類庫來使用正則表達式?

性能問題

請參考MSDN網站的關於這種用法的性能描述:

在查詢語句中,開發人員應該將 CLR 視為無法聲明的邏輯處理的有效替代。Microsoft建議在基於CLR的編程可以補充T-SQL查詢語言的表現力的情況下使用CLR集成。例如需要在可以被稱為函數(LIKE-function)的查詢中嵌入過程邏輯。這包括以下情況:

  • 根據存儲在數據庫的數據表中的數據,以行為單位進行復雜計算(必須使用邏輯過程表達)。這可能涉及將這些結果返回給客戶端,或使用計算過濾發送給客戶端一組數據;

  • 在 SELECT 查詢或 DML 結構查詢語句中的 From 子句,需要使用過程邏輯來評估返回結果。

MS SQL Server 2000或以上版本引入了 T-SQL 函數(標量和表值函數)。如果使用 SQL Server 2005及以上版本,使用 CLR 語言更容易編寫,因為開發者能更廣泛地使用 .Net Framework 提供的類庫。此外,CLR 提供了豐富的、但 T-SQL 不具備的數據結構(如數組、集合等),因此在 CLR 及 T-SQL 不同的執行模型中,能顯著提升執行性能。

一般來講,函數是在 T-SQL 中使用 CLR 時一個很好的選擇。因為很少需要從函數內訪問數據庫:數據庫中的值通常作為參數傳遞。這樣就能達到CLR的優點,在計算任務上比T-SQL更好。

相關代碼

Part I -- Like 子句的擴展

首先,必須讓 MS SQL Server 允許使用 CLR(默認是禁止的)。執行下面的語句:

如何在SQL Server中調用類庫來使用正則表達式?

如果要還原為禁止使用 CLR,則執行下面的語句:

如何在SQL Server中調用類庫來使用正則表達式?

從這裡,我們創建一個程序集,該程序集是Regular Expression .NET類的包裝器。要在C#/ .NET中為MS SQL Server創建用戶定義的函數,只需創建一個庫項目,即可創建一個類,並public static在將來添加將成為SQL函數的方法。而且,SqlFunctionAttribute必須從這些方法中防止每一種。它用於將用戶定義聚合的方法定義標記為SQL Server中的一個功能。對於我們的RegularExpressionLike方法,我們有一個方法如圖所示:

如何在SQL Server中調用類庫來使用正則表達式?

接下來,對該類庫進行編譯打包並在 MS SQL Server 中註冊該類庫。可以執行下面的語句:

如何在SQL Server中調用類庫來使用正則表達式?

順便說一下,要取消在 MS SQL Server 中的註冊,可執行以下語句:

如何在SQL Server中調用類庫來使用正則表達式?

好了,可以在 T-SQL 中使用該類庫了:

  • 將類庫 與 SQL Server 的函數對象綁定:

如何在SQL Server中調用類庫來使用正則表達式?

  • 在 T-SQL 中使用 RegExpLike 數據庫函數來測試使用正則表達式的效果:

如何在SQL Server中調用類庫來使用正則表達式?

  • 上述角本運行的結果如下:

如何在SQL Server中調用類庫來使用正則表達式?

Part II -- 文本解析

下一演示的是通過使用正則表達式模式從給定的文本中提取字符串。該函數返回表值結果,即,函數執行的結果是具有一些數據的表。結果有三列:字符的起始位置、詞語字符串的長度及單詞字符串。CLR表示用於表值函數的流模型,可確保在第一行可用後立即消費結果,而不是等待整個表的填充。它為最終用戶和性能提供了很多優勢,當然,這會導致執行中的額外複雜性。用戶定義的表值函數需要實現兩種public static方法:一種是由MS SQL Server調用的主方法,並返回一個IEnumerable對象,而另一個是由第一個調用來填充錶行的輔助方法。如果我們看下面的代碼,全部將會很清楚:

如何在SQL Server中調用類庫來使用正則表達式?

GetMatches將所有匹配的元素作為MatchCollection對象返回,FillMatch被每個匹配的對象調用。我們可以從參數列表中看到它:首先是對象引用,其餘的是由屬性標記的out變量。剩下的變量決定了列的性質。您必須在該SqlFunction.FillRowMethodName屬性中指明填充方法名稱; 另一方面,它允許一些靈活性。現在,我們構建程序集,再次在MS SQL Server中註冊,因為其強大的名稱被建築物更改,並創建了一個目標表值函數:

如何在SQL Server中調用類庫來使用正則表達式?

現在,我們可以通過某種模式從一些文本中提取字符串。例如,讓我們從小寫“a”開始的文本中獲取所有單詞:

如何在SQL Server中調用類庫來使用正則表達式?

得到的結果如下:

如何在SQL Server中調用類庫來使用正則表達式?

請注意,腳本不會返回任何“ASP.NET”令牌,因為它們以大寫“A”開頭。如果您想在匹配發生時忽略大小寫,則必須具有一個新的功能,或者只要添加一個參數,Regex.Matches() 方法如下所示:

如何在SQL Server中調用類庫來使用正則表達式?

好的,就到這吧,更深層次的內容,讀者可以自己嘗試一下。

相關推薦

推薦中...