應用C#和SQLCLR編寫SQL Server用戶定義函數

摘要: 文檔闡述使用C#和SQLCLR爲SQL Server編寫用戶定義函數,並演示用戶定義函數在T-SQL中的應用。文檔中實現的 Base64 編碼解碼函數和正則表達式函數屬於標量值函數,字符串分割函數屬於表值函數,而平方平均數函數屬於聚合函數。
環境 要求:SQL Server 2005/2008,Visual Studio 2005/2008,C# 2.0。
 
本頁內容
 
概述
微軟在推出SQL Server 2005後,實現了對.NET CLR的集成,使得.NET代碼可在SQL Server服務器進程中執行。開發人員經過C#和SQLCLR可輕鬆建立存儲過程、用戶定義函數、觸發器和用戶定義類型等功能,改變了之前只能經過T- SQL語言來實現這些功能的局面。做爲SQLCLR的典型應用,本文將經過C#編寫Base64編碼解碼函數、正則表達式函數、字符串分割函數以及 平方平均數函數 來演示如何爲SQL Server編寫 標量值函數、表值函數和聚合函數。
 
啓用SQLCLR
在講解具體函數以前,咱們先來了解一下如何啓用SQLCLR,並經過Visual Studio 2005/2008建立數據庫項目,最後部署.NET程序集到SQL Server的過程。
默認狀況下,SQL Server的SQLCLR是禁用的,要使用SQLCLR須要經過sp_configure系統存儲過程設置服務器配置選項來啓用,下面顯示了默認狀況下的設置。

 

sp_configure 'clr enabled' ;
name                                minimum     maximum     config_value run_value
----------------------------------- ----------- ----------- ------------ -----------
clr enabled                         0           1           0            0
下面用T-SQL來啓用SQLCLR,並查看修改後的設置信息。

 

sp_configure 'clr enabled' , 1;
GO
RECONFIGURE ;
GO
sp_configure 'clr enabled' ;
name                                minimum     maximum     config_value run_value
----------------------------------- ----------- ----------- ------------ -----------
clr enabled                         0           1           1            1
Visual Studio 提供了一個項目模板來創建用於數據庫開發的項目,在新建項目中選擇Visual C#,而後選擇數據庫項目,在對話框中設置項目名稱爲SqlServer.SqlClr.Functions,爲項目添加一個C#類文件並命名類名稱爲 UserDefinedFunctions,並添加一個靜態公共的HelloSqlClr函數,補充代碼結果以下所示。

 

using System;
using System.Data;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
 
public class UserDefinedFunctions
{
    [Microsoft.SqlServer.Server.SqlFunction (Name = "Clr_HelloSqlClr" )]
    public static SqlString HelloSqlClr(SqlString input)
    {
        return input;
    }
}
UserDefinedFunctions 類引用了System.Data.SqlTypes命名空間。 System.Data.SqlTypes 命名空間包含了SQL Server 中本地數據類型對應的類型,好比上面的SqlString類型對應於SQL Server的char、nchar、text、ntext、nvarchar、varchar數據類型。這些類提供一種比.NET Framework公共語言運行庫(CLR)提供的數據類型更快更安全的替代方案。使用此命名空間中的類有助於防止類型轉換錯誤時出現精度損失的狀況。
UserDefinedFunctions 類還引用了Microsoft.SqlServer.Server命名空間,該命名空間包 含將 Microsoft .NET Framework公共語言運行庫(CLR)集成到Microsoft SQL Server和SQL Server 數據庫引擎進程執行環境時所要用到的類、接口和枚舉。上面的代碼咱們爲 HelloSqlClr 指定了SqlFunction特性,並設置Name屬性,這使得經過Visual Studio輕鬆實現託管用戶定義函數在SQL Server中的部署。
若是採用非自動化方式部署須要經過C#編譯器編譯源代碼,並經過T-SQL語言進行程序集安裝,最後進行函數註冊等步驟。
下面經過CSC進行C#代碼的編譯,輸出 SqlServer.SqlClr.Functions.dll 程序集。

 

csc /target:library /out:SqlServer.SqlClr.Functions.dll UserDefinedFunctions.cs
經過SQL Server Management Studio執行T-SQL加載SqlServer.SqlClr.Functions.dll程序集到SQL Server中。

 

CREATE ASSEMBLY [SqlServer.SqlClr.Functions]
FROM 'D:/SqlServer SqlClr Solution/SqlServer.SqlClr.Functions/SqlServer.SqlClr.Functions.dll'
WITH PERMISSION_SET = SAFE
當程序集安裝到SQL Server中後,能夠經過如下T-SQL來查看程序集。

 

SELECT * FROM sys . assemblies
下面的T-SQL註冊程序集中包含的 HelloSqlClr 函數。

 

CREATE FUNCTION [dbo] . [Clr_HelloSqlClr] ( @input [nvarchar] ( 128))
RETURNS [nvarchar] ( 128) WITH EXECUTE AS CALLER
AS
EXTERNAL NAME [SqlServer.SqlClr.Functions] . [UserDefinedFunctions] . [HelloSqlClr]
以上工做完成後,就能夠經過T-SQL來調用用戶定義函數了。

 

SELECT dbo . Clr_HelloSqlClr ( 'Hello sqlclr' );
---------------------------
Hello sqlclr
 
本節簡單介紹了經過C#實現用戶定義函數並部署應用的通常流程,接下去的章節來具體實現幾個經常使用的功能函數,其中 Base64 編碼解碼函數和正則表達式函數屬於標量值函數,字符串分割函數屬於表值函數,而平方平均數函數屬於聚合函數。
 
Base64 編碼解碼函數
SQL Server 雖然可以經過FOR XML語法間接實現對數據的Base64編碼,但到目前爲止實際上並無提供可直接調用Base64編碼解碼的函數,這難免讓人感到意外,不過經過SQLCLR可輕鬆解決這一問題。
下面經過C#爲UserDefinedFunctions類增長了Base64編碼和解碼函數。Convert類的ToBase64String和FromBase64String方法很好地發揮了做用,輕鬆實現了Base64編碼和解碼操做。
Base64 編碼函數。

 

[Microsoft.SqlServer.Server.SqlFunction (Name = "Clr_Base64Encode" )]
public static SqlString Base64Encode(SqlString input)
{
    if (input.IsNull)
    {
        return new SqlString (null );
    }
    byte [] array = System.Text.Encoding .UTF8.GetBytes(input.Value);
    string result = System.Convert .ToBase64String(array);
    return new SqlString (result);
}
Base64 解碼函數。

 

[Microsoft.SqlServer.Server.SqlFunction (Name = "Clr_Base64Decode" )]
public static SqlString Base64Decode(SqlString input)
{
    if (input.IsNull)
    {
        return new SqlString (null );
    }
    byte [] array = System.Convert .FromBase64String(input.Value);
    string result = Encoding .UTF8.GetString(array);
    return new SqlString (result);
}
 
對SqlServer.SqlClr.Functions項目進行編譯,並部署 SqlServer.SqlClr.Functions.dll到SQL Server,在SQL Server對象資源管理器對應數據庫的標量值函數目錄下能夠發現增長了Clr_Base64Encode和Clr_Base64Decode函數,經過 右鍵修改菜單查看Clr_Base64Encode函數對應的T-SQL代碼。

 

ALTER FUNCTION [dbo] . [Clr_Base64Encode] ( @input [nvarchar] ( 4000))
RETURNS [nvarchar] ( 4000) WITH EXECUTE AS CALLER
AS
EXTERNAL NAME [SqlServer.SqlClr.Functions] . [UserDefinedFunctions] . [Base64Encode]
使用T-SQL進行應用測試。

 

SELECT dbo . Clr_Base64Encode ( 'StarCraft|WarCraft|Diablo' ) AS ITEM ;
SELECT dbo . Clr_Base64Decode ( 'U3RhckNyYWZ0fFdhckNyYWZ0fERpYWJsbw==' ) AS ITEM ;
ITEM
-------------------------------------------------------
U3RhckNyYWZ0fFdhckNyYWZ0fERpYWJsbw==
ITEM
-------------------------------------------------------
StarCraft|WarCraft|Diablo
 
正則表達式函數
正則表達式爲字符串處理提供了強大的功能,惋惜的是目前SQL Server尚未提供對正則表達式的支持。雖然Oracle早期版本中也缺少對SQL正則表達式支持,不過在Oracle 10g中內建了符合POSIX 標準的正則表達式,增長了REGEXP_LIKE、REGEXP_INSTR、REGEXP_SUBSTR和EGEXP_REPLACE四個新函數。本節 咱們將經過C#和SQLCLR來實現相似的正則表達式函數。
 
在.NET中使用正則表達式須要用到 System.Text.RegularExpressions命名空間中的類型,核心類爲Regex,那麼咱們繼續來完善 UserDefinedFunctions類,添加正則表達式匹配函數、正則表達式匹配索引函數、正則表達式匹配項函數和正則表達式替換函數這四個函數。
正則表達式匹配函數。RegexLike函數功能爲對字符串進行模式匹配查詢,若是匹配成功返回true,失敗返回false。函數接收三個參數,分別對應輸入字符串,匹配模式,和正則表達式選項,在函數內部經過Regex.IsMatch方法返回匹配結果。

 

[Microsoft.SqlServer.Server.SqlFunction (Name = "Clr_RegexLike" )]
public static SqlBoolean RegexLike(SqlString input, SqlString pattern, SqlInt32 options)
{
    if (input.IsNull || pattern.IsNull)
    {
        return new SqlBoolean (false );
    }
    bool result = Regex .IsMatch(input.Value, pattern.Value, (RegexOptions )options.Value);
    return new SqlBoolean (result);
}
 
正則表達式匹配索引函數。RegexMatchIndex函數功能爲對字符串進行模式匹配查找,若是存在匹配,返回第一個匹配項的第一個字符的索引,若是不存在返回-1。

 

[Microsoft.SqlServer.Server.SqlFunction (Name = "Clr_RegexMatchIndex" )]
public static SqlInt32 RegexMatchIndex(SqlString input, SqlString pattern, SqlInt32 options)
{
    if (input.IsNull || pattern.IsNull)
    {
        return new SqlInt32 (-1);
    }
    Match match = Regex .Match(input.Value, pattern.Value, (RegexOptions )options.Value);
    if (match.Success)
    {
        return new SqlInt32 (match.Captures[0].Index);
    }
    return new SqlInt32 (-1);
}
 
正則表達式匹配項函數。RegexMatchValue函數功能爲對字符串進行模式匹配查找,若是存在匹配,返回第一個匹配項的內容,若是不存在,返回空字符串。

 

[Microsoft.SqlServer.Server.SqlFunction (Name = "Clr_RegexMatchValue" )]
public static SqlString RegexMatchValue(SqlString input, SqlString pattern, SqlInt32 options)
{
    if (input.IsNull || pattern.IsNull)
    {
        return SqlString .Null;
    }
    Match match = Regex .Match(input.Value, pattern.Value, (RegexOptions )options.Value);
    if (match.Success)
    {
        return new SqlString (match.Captures[0].Value);
    }
    return SqlString .Null;
}
 
正則表達式替換函數。RegexReplace函數功能爲對字符串進行模式查找替換,相比前面的函數,增長了一個替換內容參數,內部經過Regex.Replace方法對查找到的匹配使用新的字符串進行替換。

 

[Microsoft.SqlServer.Server.SqlFunction (Name = "Clr_RegexReplace" )]
public static SqlString RegexReplace(SqlString input, SqlString pattern, SqlString replacement, SqlInt32 options)
{
    if (input.IsNull || pattern.IsNull || replacement.IsNull)
    {
        return input;
    }
    string s = Regex .Replace(input.Value, pattern.Value, replacement.Value, (RegexOptions )options.Value);
    return new SqlString (s);
}
 
四個正則表達式函數都提供了一個SqlInt32類型的options參數,該 參數功能對應.NET中的RegexOptions枚舉,RegexOptions帶有FlagAttribute特性,也就是說多個不一樣的枚舉值能夠組 合在一塊兒,所以若是要正確設置Options,須要對RegexOptions進行一些瞭解,下面是經過NUnit確認的RegexOptions枚舉項 對應的值,並對枚舉組合進行單元測試。

 

[Test ]
public void RegexOptionsTest()
{
    Assert .AreEqual((int )RegexOptions .None,0);
    Assert .AreEqual((int )RegexOptions .IgnoreCase,1);
    Assert .AreEqual((int )RegexOptions .Multiline,2);
    Assert .AreEqual((int )RegexOptions .ExplicitCapture,4);
    Assert .AreEqual((int )RegexOptions .Compiled,8);
    Assert .AreEqual((int )RegexOptions .Singleline,16);
    Assert .AreEqual((int )RegexOptions .IgnorePatternWhitespace,32);
    Assert .AreEqual((int )RegexOptions .RightToLeft,64);
    Assert .AreEqual((int )RegexOptions .ECMAScript, 256);
    Assert .AreEqual((int )RegexOptions .CultureInvariant,512);
    Assert .AreEqual((int )(RegexOptions .IgnoreCase | RegexOptions .Multiline), 3);
}
 
再次對SqlServer.SqlClr.Functions項目進行編譯和部 署,在SQL Server對象資源管理器對應數據庫的標量值函數目錄下能夠發現增長了Clr_RegexLike、Clr_RegexMatchIndex、 Clr_RegexMatchValue和Clr_RegexReplace四個函數。
爲測試正則表達式函數,準備一張GameInfo表並寫入一些測試數據。

 

CREATE TABLE [dbo] . [GameInfo] (
    [Id] [int] NOT NULL,
    [Name] [nvarchar] ( 32) NOT NULL
) ON [PRIMARY]
GO
 
INSERT INTO [dbo] . [GameInfo] ( Id , Name ) VALUES ( 1, 'StarCraft' );
INSERT INTO [dbo] . [GameInfo] ( Id , Name ) VALUES ( 2, 'WarCraft' );
INSERT INTO [dbo] . [GameInfo] ( Id , Name ) VALUES ( 1, 'Diablo' );
下面的T-SQL對四個正則表達式函數進行了測試。

 

SELECT * FROM dbo . GameInfo WHERE dbo . Clr_RegexLike ( Name , 'Craft$' , 0) = 1;
Id          Name
----------- --------------------------------
1           StarCraft
2           WarCraft
 
SELECT Name , dbo . Clr_RegexMatchIndex ( Name , 'Craft$' , 0) AS MIndex FROM dbo . GameInfo ;
Name                             MIndex
-------------------------------- -----------
StarCraft                        4
WarCraft                         3
Diablo                           -1
 
SELECT Name , dbo . Clr_RegexMatchValue ( Name , 'craft$' , 1) AS MValue FROM dbo . GameInfo ;
Name                             MValue
-------------------------------- ------------------------------
StarCraft                        Craft
WarCraft                         Craft
Diablo                           NULL
 
SELECT Name , dbo . Clr_RegexReplace ( Name , '^StarCraft$' , 'StarCraftII' , 0) AS Name2 FROM dbo . GameInfo ;
Name                             Name2
-------------------------------- -------------------------------
StarCraft                        StarCraftII
WarCraft                         WarCraft
Diablo                           Diablo
 
字符串分割函數
字符串分割是字符串處理的一項基本功能,在.NET中經過 String.Split方法能夠輕鬆實現按特定字符組或字符串組進行的分割,並返回分割後的子字符串數組,固然Regex.Split方法提供了更爲強 大的分割功能,支持由正則表達式匹配項定義的分割字符串將輸入的字符串拆分爲一個子字符串數組。相對於.NET提供對字符串處理的強大支持,SQL Server就顯得相對乏力,下面就來實現SQLCLR版本的Split函數。
因爲字符串分割後返回的是數組,在SQL Server中體現爲多條記錄,於是不一樣於前面的Base64編碼解碼和正則表達式等標量值函數,Split函數屬於表值函數(TVF)。要實現表值函數 除了爲SqlFuctionAttribute特性設置Name屬性外,還須要指定FillRowMethodName和TableDefinition 兩個屬性,FillRowMethodName屬性指定行填充方法的名稱,而TableDefinition屬性定義返回的記錄集的表結構,下面顯示了完 整實現代碼。

 

[Microsoft.SqlServer.Server.SqlFunction (Name = "Clr_Split" , FillRowMethodName = "SplitFillRow" , TableDefinition = "item nvarchar(256)" )]
public static IEnumerable Split(SqlString input, SqlString separators)
{
    string [] array;
    if (input.IsNull)
    {
        array = new string [] { null };
    }
    else if (separators.IsNull)
    {
        array = new string [] { input.Value };
    }      
    else
    {
        string [] separatorsArray = separators.Value.Split(new char [] { ',' }, StringSplitOptions .RemoveEmptyEntries);
        array = input.Value.Split(separatorsArray, StringSplitOptions .None);
    }       
    return array;
}
 
private static void SplitFillRow(Object obj, ref SqlString item)
{
    if (obj != null )
    {
        item = (string )obj;
    }
}
不難發現表值函數須要返回IEnumerable接口,行填充函數能夠指定任意名稱,上面的代碼還指定數據表只包含一個item列。
經過Visual Studio對SqlServer.SqlClr.Functions項目進行編譯和部署,在SQL Server對象資源管理器對應數據庫的表值函數目錄下發現增長了Clr_Split函數,經過修改右鍵菜單查看部署生成的T-SQL代碼。

 

ALTER FUNCTION [dbo] . [Clr_Split] ( @input [nvarchar] ( 4000), @separators [nvarchar] ( 4000))
RETURNS  TABLE (
    [item] [nvarchar] ( 256) NULL
) WITH EXECUTE AS CALLER
AS
EXTERNAL NAME [SqlServer.SqlClr.Functions] . [UserDefinedFunctions] . [Split]
部署工具對於item列生成nvarchar(4000)數據類型,能夠在T-SQL中修改數據長度大小。下面經過兩條T-SQL語句對Clr_Split函數進行測試,輸出同一結果。

 

SELECT * FROM dbo . Clr_Split ( 'StarCraft|WarCraft|Diablo' , '|' );
SELECT * FROM dbo . Clr_Split ( 'StarCraft|WarCraft//Diablo' , '|,//' );
item
-----------------------------
StarCraft
WarCraft
Diablo
 
下面的C#代碼實現了Split函數的另一個版本,返回的記錄集包含兩列,除了分割值還增長了分割序號。

 

[Microsoft.SqlServer.Server.SqlFunction (Name = "Clr_SplitWithOrder" , FillRowMethodName = "SplitWithOrderFillRow" , TableDefinition = "orderId int, item nvarchar(4000)" )]
public static IEnumerable SplitWithOrder(SqlString input, SqlString separators)
{
    Dictionary <int , string > dictionary = new Dictionary <int , string >();
    if (input.IsNull)
    {
        dictionary.Add(1, null );
    }
    else if (separators.IsNull)
    {
        dictionary.Add(1, input.Value);
    }
    else
    {
        string [] separatorsArray = separators.Value.Split(new char [] { ',' }, StringSplitOptions .RemoveEmptyEntries);
        string [] array = input.Value.Split(separatorsArray, StringSplitOptions .None);
        for (int i = 0; i < array.Length; i++)
        {
            dictionary.Add(i + 1, array[i]);
        }
    }       
    return dictionary;
}
 
private static void SplitWithOrderFillRow(Object obj, ref SqlInt32 orderid, ref SqlString item)
{
    if (obj != null )
    {
        KeyValuePair <int , string > kvp = (KeyValuePair <int , string >)obj;
        orderid = kvp.Key;
        item = kvp.Value;
    }
}
經過T-SQL對SplitWithOrder函數進行測試。

 

SELECT * FROM dbo . Clr_SplitWithOrder ( 'StarCraft|WarCraft//Diablo' , '|,//' ) ORDER BY orderId DESC ;
orderId     item
----------- ----------------------------------------
3           Diablo
2           WarCraft
1           StarCraft
 
平方平均數函數
聚合函數的功能是對一組值進行計算並返回單個值。在SQL Server 2005以前,數據庫引擎只支持內置聚合函數,例如常見的SUM、MAX、AVG和COUNT等函數,這些聚合函數對一組輸入標量值執行操做,而且從該組 值生成單個聚合值。在SQL Server 2005版本推出後,SQL Server同.NET CLR集成,使得開發人員可以經過.NET託管代碼建立自定義聚合函數,而且使這些函數可應用於T-SQL編程。
本節,咱們經過實現平方平均數函數來說解如何使用.NET實現聚合函數。在 Visual Studio中經過解決方案管理器右鍵點擊SqlServer.SqlClr.Functions項目打開「添加」子菜單選擇「聚合」菜單項,項目中會新 增長包含聚合函數模板的Aggregate1.cs文件,接下去只須要在模板裏面添加代碼實現功能邏輯便可。

 

using System;
using System.Data;
using System.Data.SqlClient;
using System.Data.SqlTypes;
using Microsoft.SqlServer.Server;
 
[Serializable ]
[Microsoft.SqlServer.Server.SqlUserDefinedAggregate (Format .Native)]
public struct Aggregate1
{  
public void Init()
    {
    }
    public void Accumulate(SqlString Value)
    {
    }
    public void Merge(Aggregate1 Group)
    {
    }
    public SqlString Terminate()
    {
        return new SqlString ("" );
    }   
    private int var1;
}
 
聚合函數模板包含一個Aggregate1結構,該結構除了聲明可序列化外還指 定了SqlUserDefinedAggregate特性來指示結構類型應如何註冊爲用戶定義的聚合。SqlUserDefinedAggregate的 Format屬性經過Microsoft.SqlServer.Server.Format枚舉來指定聚合的序列化格式,若是在聚合函數中只使用值類型成 員,那麼能夠設置Format屬性爲Format.Native,若是設置爲Format.UserDefined,開發人員須要本身實現 Microsoft.SqlServer.Server.IBinarySerialize接口以支持序列化。另外 SqlUserDefinedAggregate特性類還包含 IsInvariantToNulls 和IsInvariantToDuplicates等其餘屬性,關於這些屬性功能具體能夠參考MSDN。
Aggregate1 包含4個方法,這是查詢處理器計算聚合所用的方法,若是編程人員對BizTalk組件開發比較熟悉,你會發現聚合函數編程相似於BizTalk中的自定義Functoid組件編程。MSDN文檔對4個方法進行了具體解釋。
Init 方法。

 

public void Init();
查詢處理器使用此方法初始化聚合的計算。對於查詢處理器正在聚合的每一個組調用此方法一次。查詢處理器能夠選擇重用聚合類的同一實例來計算多個組的聚合。Init 方法應在上一次使用此實例後根據須要執行清除,並容許從新啓動新的聚合計算。
Accumulate 方法。

 

public void Accumulate(input_type Value);
查詢處理器使用此方法累計聚合值。對於正在聚合的組中的每一個值調用此方法一次。 查詢處理器僅在爲聚合類的指定實例調用Init方法以後才調用此方法。此方法的實現應更新實例的狀態以反映正在傳遞的參數值的累計。input_type 參數是託管的 SQL Server 數據類型,該數據類型與CREATE AGGREGATE 語句中input_sqltype 所指定的本機SQL Server數據類型等效。
Merge 方法。

 

public void Merge(Aggregate1 Group);
此方法能夠將此聚合的另外一實例與當前實例合併。查詢處理器使用此方法合併聚合的多個部分計算。
Terminate 方法。

 

public return_type Terminate();
此方法完成聚合計算並返回聚合的結果。return_type返回值類型應是託管的SQL Server數據類型,該數據類型是CREATE AGGREGATE語句中指定的return_sqltype 的託管等效類型。
 
經過以上的介紹,實現平方平均數聚合函數就變得比較簡單,修改結構名稱爲QuadraticMean,並設置兩個內部變量, totalValue 變量用來存儲輸入數據的平方和,而count變量用來存儲輸入數據的個數,最後經過System.Math.Sqrt方法計算返回平方平均數,下面是實現代碼。

 

[Serializable ]
[Microsoft.SqlServer.Server.SqlUserDefinedAggregate (Format .Native,IsInvariantToNulls = true , IsInvariantToDuplicates = false )]
public struct QuadraticMean
{
    private double totalValue;
    private int count;
 
    public void Init()
    {
        totalValue = 0.0;
        count = 0;
    }
 
    public void Accumulate(SqlDouble input)
    {
        if (input.IsNull)
        {
            return ;
        }
        totalValue += input.Value * input.Value;
        count++;
    }
 
    public void Merge(QuadraticMean Group)
    {
        totalValue += Group.totalValue;
        count = Group.count;
    }
 
    public SqlDouble Terminate()
    {
        double result = Math .Sqrt(totalValue / count);
        return new SqlDouble (result);
    }
}
 
經過Visaul Studio編譯和部署項目,在SQL Server對象資源管理器對應數據庫的聚合函數目錄下發現增長了QuadraticMean函數,查看生成的T-SQL代碼。

 

CREATE AGGREGATE [dbo] . [QuadraticMean]
( @input [float] )
RETURNS [float]
EXTERNAL NAME [SqlServer.SqlClr.Functions] . [QuadraticMean]
結合AVG函數對QuadraticMean函數進行測試。

 

SELECT avg ( Id ), dbo . QuadraticMean ( Id ) FROM dbo . GameInfo ;
----------- ----------------------
2           2.16024689946929
 
總結
SQL Server 同.NET CLR的緊密集成使得.NET開發人員可以快速實現SQL Server擴展功能編程,通常使用SQLCLR來實現專門執行計算的操做功能,使用T-SQL來實現基於集合的操做功能。該文檔全面講解了如何經過C# 和SQLCLR爲SQL Server實現標量值、表值和聚合3類用戶定義函數,並演示用戶定義函數在T-SQL中的實際應用。 Base64 編碼解碼函數、正則表達式函數、字符串分割函數和平方平均數函數均屬於基礎函數,可被方便應用到實際業務系統中。
相關文章
相關標籤/搜索