初探SQL Server CLR 整合

來源:互聯網
上載者:User

sqlserver
2005中,加入了很多新特性。對於開發人員來講,最值得一提的是對XML的支援和CLR整合。當然,還有一些關於“高可用“(資料庫叢集/資料庫鏡像/記錄傳送等)的新特性,比較適合DBA,感興趣的朋友可以瞭解一下。

相信很多人和我一樣,一直很希望在sqlserver中非常靈活地編程,實現各種功能(能像在VS中使用C#編程一樣的爽)。但是未能如願,暫不說開發環境的問題(代碼補全,配色等)。最主要的是,T-SQL這東西確實不適合做複雜的運算(對我這種菜鳥來講確實有難度。對那些大牛來說估計不難),也缺乏物件導向編程的靈活性。連一些基本的資料結構也沒有辦法實現,更別提什麼物件導向了。

有了sqlserver
CLR整合後,這一切似乎就變了。什麼是CLR ,到底什麼是CLR整合?先看看MSDN的解釋吧。

通過在 Microsoft SQL Server 中託管 CLR(稱為 CLR 整合),可以在Managed 程式碼中編寫預存程序、觸發器、使用者定義函數、使用者定義型別和使用者定義彙總函式。 因為Managed 程式碼在執行之前會編譯為機器碼,所以,在有些方案中可以大大提高效能。

通俗點講,就是sqlserver 2005 版本之後,資料庫引擎中加入了 .NET Framework 的通用語言執行平台 (CLR) 組件,可以更方便和.NET應用程式互動。

首先,建立一個sqlserver
CLR 資料庫專案,



項目建立好之後,可以開啟試圖,看看結構,裡面只包含一些測試樣本的sql指令碼。

接下來,建立一個普通的C#類,在類中定義一個方法。如下:

using System;using System.Collections.Generic;using System.Linq;using System.Text;using Microsoft.SqlServer.Server;namespace SqlServerProject1{   public  class demo    {       [Microsoft.SqlServer.Server.SqlProcedure]       public static void ClrProc() {           SqlContext.Pipe.Send("Hello World");       }    }}

記得要引入using Microsoft.SqlServer.Server這個命名空間。在方法體中,使用了如下代碼

SqlContext.Pipe.Send("Hello World");

可以理解為像用戶端發送一條結果,就像Response.Write輸出一樣。

給這個普通的方法,加上[Microsoft.SqlServer.Server.SqlProcedure]特性。其意義就是標記自己是個CLR
預存程序。

註:Attribute,有的人也稱作屬性,為了避免不和物件導向中的get/set混淆,故本人習慣稱之為”特性“。和java中的註解差不多。

編譯通過後,可以選擇直接在VS的產生菜單下選擇”部署“,也可以去資料庫中手動建立。


開啟指定資料庫的查詢時段,開始寫指令碼,檢查資料庫配置,看看是否開啟了clr支援,沒有的話則手動去開啟:

--查看系統配置SELECT * FROM sys.configurationsORDER BY nameGO--啟用clrsp_configure 'clr enabled',1goRECONFIGURE;GO

準備完畢後,開始建立程式集和CLR預存程序:

--建立程式集CREATE ASSEMBLY SqlServerProject1 FROM N'C:\Users\Administrator\Documents\visual studio 2010\Projects\Database1\SqlServerProject1\bin\Debug\SqlServerProject1.DLL'WITH permission_set=SAFEGO----DROP ASSEMBLY SqlServerProject1--go--建立CLR預存程序 (程式集.命名空間.類型.方法名)CREATE PROC dbo.helloworldAS EXTERNAL NAME SqlServerProject1.[SqlServerProject1.demo].ClrProcgo--執行Clr預存程序EXEC helloworldgo

注意,之前的項目中編譯後的DLL檔案的路徑(推薦使用絕對路徑),許可權直接給safe。建立CLR預存程序,其實和普通的proc差不多,只不過多了一句(大致意思就是指定程式集中指定的命名空間下的類和對應的方法)

可以像調用普通的預存程序一樣去執行它。看看結果,果然有了”HelloWorld“。呵呵。當然,這隻是最簡單的,目的是教大家如何建立。

當然,也可以建立複雜一點的預存程序/函數/觸發器等。我就拿預存程序為例,做一個稍微複雜的,返回一個SqlDataReader對象。

直接在項目上右鍵,建立,選擇預存程序即可(剛才建立一個普通類,是為了讓大家理解其基本的實現和對應關係)。



建好預存程序後,可以往方法裡面添加一些簡單的代碼,執行一個基本的單表查詢,然後返回給用戶端一個SqlDataReader對象。代碼如下:

using System;using System.Data;using System.Data.SqlClient;using System.Data.SqlTypes;using Microsoft.SqlServer.Server;public partial class StoredProcedures{    [Microsoft.SqlServer.Server.SqlProcedure]    public static void StoredProcedure1()    {        // 在此處放置代碼        SqlConnection conn = new SqlConnection("context connection=true");        try        {            conn.Open();            SqlCommand cmd = new SqlCommand("SELECT count(*) FROM dbo.TempCatalog", conn);            SqlDataReader dr = cmd.ExecuteReader();            SqlContext.Pipe.Send(dr);        }        catch (Exception)        {            conn.Close();        }    }};

編譯完成後,可以在VS的產生菜單下選擇”部署“(會自動部署到sqlserver中,並覆蓋原來的)。當然,也可以手動去重新載入程式集並建立需要的預存程序。

在sqlserver中建立好並執行預存程序後,檢查一下結果,看是不是你想要的?

提示:手動重複載入、建立,可能會衝突。需要先刪除後再重新建立。可以在sqlserver物件瀏覽器中檢查,也可以使用如下sql語句查詢相關資訊。

SELECT * FROM sys.assembliesSELECT * FROM sys.assembly_files

簡單的例子做完了,優點是可想而知的。那到底啥時候應用CLR,啥時候寫T-sql呢?我覺得具體要根據實際業務需求和應用情境去判斷了。

根據有些微軟方面的專家提示,在下面幾種情況下,應該考慮使用CLR: 
SQL中涉及大量的邏輯判斷和邏輯運算。比如需要在資料庫層級自訂密碼編譯演算法,解密演算法等。 
T-SQL無法處理需求。比如需要在SQL中進行Regex的判斷等。 
邏輯判斷或者迴圈分支過於複雜,有時需要使用大量遊標進行處理(也不一定使用遊標就會變慢,關鍵看敲代碼的人)。

本文出自http://blog.csdn.net/dinglang_2009,轉載請註明出處。




相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.