處理常見數據庫編程任務和問題
前一節在高層次上對基於 CLR 的編程與 T-SQL、中間層和擴展存儲過程 (XP) 進行了比較。在這一節中,我們將考慮數據庫應用程序開發人員經常遇到的一些編程任務和模型,並且討論如何使用 CLR(以及在一些情況下如何不使用)進行處理。
使用 Framework 庫進行數據驗證
SQL Server 2005 中的 CLR 集成允許用戶利用 .Net Framework 類庫提供的豐富功能來解決其數據庫編程問題。
常規表達式的使用可以很好地說明 CLR 集成如何增強了驗證和過濾功能。在處理數據庫中存儲的文本數據方面,常規表達式提供的模式匹配功能比通過 T-SQL 查詢語言中的 LIKE 運算符可用的模式匹配功能多。考慮以下 C# 代碼,它只是 System.Text.RegularExpressions 命名空間中的 RegEx 類的一個簡單包裝:
using System;
using System.Data.Sql;
using System.Data.SqlTypes;
using System.Text.RegularExpressions;
public partial class StringFunctions
{
[SqlFunction(IsDeterministic = true, IsPrecise = true)]
public static bool RegExMatch(string pattern, string matchString)
{
Regex r1 = new Regex(pattern.TrimEnd(null));
return r1.Match(matchString.TrimEnd(null)).Success;
}
[SqlFunction(IsDeterministic = true, IsPrecise = true)]
public static SqlString ExtractAreaCode(string matchString)
{
Regex r1 = new Regex("\((?[1-9][0-9][0-9])\)");
Match m = r1.Match(matchString);
if (m.Success)
return m.Value.Substring(1, 3);
else return SqlString.Null;
}
};
假設 StringFunctions.RegExMatch 和 StringFunctions.ExtractAreaCode 方法已經被注冊為帶有 RETURNS NULL ON NULL INPUT 選項的數據庫中的用戶定義函數(這允許該函數在任何輸入都為 NULL 時返回 NULL,這樣在該函數內就沒有特殊的 NULL 處理代碼):
現在,可以在使用上述代碼的表的列中定義約束,以驗證電子郵件地址和電話號碼,如下所示:
create table Contacts
(
FirstName nvarchar(30),
LastName nvarchar(30),
EmailAddress nvarchar(30) CHECK
(dbo.RegExMatch('[a-zA-Z0-9_-]+@([a-zA-Z0-9_-]+.)+(com|org|edu)',
EmailAddress) = 1),
USPhoneNo nvarchar(30) CHECK
(dbo.RegExMatch('([1-9][0-9][0-9]) [0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]',
UsPhoneNo)=1),
AreaCode AS dbo.ExtractAreaCode(UsPhoneNo) PERSISTED
)
另外,請注意 AreaCode 列是使用 dbo.ExtractAreaCode 函數從 USPhoneNo 列中取出地區代碼而得到的列。然後,可以對 AreaCode 列建立索引,這樣便於在表格中根據特定地區代碼查找聯系人的查詢。
更一般地講,此示例演示了如何利用 .Net Framework 庫來增強帶有有用函數的 T-SQL 內置函數庫,這些有用函數很難用 T-SQL 表達。