日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

SQL Server中的CLR编程——用.NET为SQL Server编写存储过程和函数

發布時間:2025/3/21 asp.net 43 豆豆
生活随笔 收集整理的這篇文章主要介紹了 SQL Server中的CLR编程——用.NET为SQL Server编写存储过程和函数 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

很早就知道可以用.NET為SQL Server2005及以上版本編寫存儲過程、觸發器和存儲過程的,不過之前開發的系統要么因為歷史原因用的是SQL2000要么根本用不著在SQL Server中啟用CLR,所以一直沒有嘗試。最近因為項目的原因,在這方面做了一個調研,現在在這里分享一下心得。
首先要說明的是要在SQL Server中啟用CLR必須是在SQL Server2005及以上版本,其次在默認情況下是沒有啟用CLR的,必須要顯示設置為啟用。比如我們要在ArticleCollectorDB數據庫中運行用.NET編寫的函數或者存儲過程,至少先要進行下面的SQL語句:

  • exec?sp_configure?'clr?enabled',?1;--在SQL?Server中啟用CLR?
  • reconfigure;?
  • go?
  • --在ArticleCollectorDB數據庫中設置TRUSTWORTHY為ON?
  • ALTER?DATABASE?[ArticleCollectorDB]?SET?TRUSTWORTHY?ON?

  • 這時可能會得到提示要重新啟動SQL Server,如果有此提示則重新啟動一下。
    接著我們在VS中進行編碼,在這里我們將分別編寫一個名為IsMatch的函數和一個名為SendMail存儲過程。在VS中創建一個名為NetSkycn.Data的類庫項目,添加一個SqlCLR的類,代碼如下:

  • using?System.Data.SqlTypes;?
  • using?System.Net;?
  • using?System.Net.Mail;?
  • using?System.Security.Permissions;?
  • using?System.Text.RegularExpressions;?
  • using?Microsoft.SqlServer.Server;?
  • ?
  • namespace?NetSkycn.Data?
  • {?
  • ///?<summary>?
  • ///?在SQL?Server環境中執行的CLR方法,注意提供給SQL?Server調用的方法必須有SqlFunction/SqlProcedure?Attribute?
  • ///?作者:周公?
  • ///?創建日期:2012-05-09?
  • ///?博客地址:http://blog.csdn.net/zhoufoxcn?http://zhoufoxcn.blog.51cto.com?
  • ///?新浪微博地址:http://weibo.com/zhoufoxcn?
  • ///?</summary>?
  • public?sealed?class?SqlCLR?
  • {?
  • ///?<summary>?
  • ///?判斷字符串是否匹配正則表達式?
  • ///?</summary>?
  • ///?<param?name="source">要匹配的文本</param>?
  • ///?<param?name="pattern">進行匹配的正則表達式</param>?
  • ///?<param?name="options">正則表達式匹配選項,1為忽略大小寫,2為多行匹配,3為忽略大小寫且多行匹配</param>?
  • ///?<returns></returns>?
  • [SqlFunction(IsDeterministic?=?true,?DataAccess?=?DataAccessKind.None)]?
  • public?static?SqlBoolean?IsMatch(string?source,?string?pattern,int?options)?
  • {?
  • if?(string.IsNullOrEmpty(source)?||?string.IsNullOrEmpty(pattern))?
  • {?
  • return?SqlBoolean.False;?
  • }?
  • RegexOptions?regexOptions=RegexOptions.None;?
  • int?optionIgnoreCase?=?1;?
  • int?optionMultiline?=?2;?
  • if?((options?&?optionIgnoreCase)?!=?0)?
  • {?
  • regexOptions?=?regexOptions?|?RegexOptions.IgnoreCase;?
  • }?
  • ?
  • if?((options?&?optionMultiline)?!=?0)?
  • {?
  • regexOptions?=?regexOptions?|?RegexOptions.Multiline;?
  • }?
  • ?
  • return?(SqlBoolean)(Regex.IsMatch(source,?pattern,?regexOptions));?
  • }?
  • ///?<summary>?
  • ///?發送郵件?
  • ///?</summary>?
  • ///?<param?name="to">收件人郵件地址</param>?
  • ///?<param?name="from">發件人郵件地址</param>?
  • ///?<param?name="subject">郵件主題</param>?
  • ///?<param?name="body">郵件內容</param>?
  • ///?<param?name="username">登錄smtp主機時用到的用戶名,注意是郵件地址'@'以前的部分</param>?
  • ///?<param?name="password">登錄smtp主機時用到的用戶密碼</param>?
  • ///?<param?name="smtpHost">發送郵件用到的smtp主機</param>?
  • [SqlProcedure]?
  • [SmtpPermission(SecurityAction.Assert)]?
  • [SecurityPermission(SecurityAction.Assert)]?
  • public?static?void?SendMail(string?to,?string?from,?string?subject,?string?body,?string?userName,?string?password,?string?smtpHost)?
  • {?
  • MailAddress?addressFrom?=?new?MailAddress(from);?
  • MailAddress?addressTo?=?new?MailAddress(to);?
  • MailMessage?message?=?new?MailMessage(addressFrom,?addressTo);?
  • message.Subject?=?subject;//設置郵件主題?
  • message.IsBodyHtml?=?true;//設置郵件正文為html格式?
  • message.Body?=?body;//設置郵件內容?
  • ?
  • SmtpClient?client?=?new?SmtpClient(smtpHost);?
  • ?
  • //設置發送郵件身份驗證方式?
  • //注意如果發件人地址是abc@def.com,則用戶名是abc而不是abc@def.com?
  • client.Credentials?=?new?NetworkCredential(userName,?password);?
  • client.Send(message);?
  • }?
  • ?
  • }?
  • }?

  • 編譯通過之后,記住類庫的物理全路徑,比如:F:\VS2008\netskycn\NetSkycn.Data\bin\Release\NetSkycn.Data.dll,在這里要強調幾點:一、對于將來提供給SQL Server調用的函數或者存儲過程必須是靜態方法,并且還必須帶有SqlFunction或者SqlProcedure屬性;二、對于一些需要訪問外部網絡資源和安全屬性的還必須添加響應的屬性(如本例中的SendMail方法,如果沒有添加響應的屬性在創建SQL Function/Procedure時會出現錯誤提示)。
    現在我們開始遵循先為SQL Server創建程序集、后創建函數或者存儲過程的順序來操作,在操作過程中用到的SQL語句如下:

  • --在ArticleCollectorDB數據庫中設置TRUSTWORTHY為ON?
  • ALTER?DATABASE?[ArticleCollectorDB]?SET?TRUSTWORTHY?ON?
  • ?
  • --如果已經存在該對象則刪除?
  • IF?EXISTS(SELECT?*?FROM?SYS.SYSOBJECTS?WHERE?NAME='SendMail'?AND?XTYPE='PC')??
  • DROP?PROCEDURE?SendMail?
  • ?
  • --如果已經存在該對象則刪除?
  • IF?EXISTS(SELECT?*?FROM?SYS.SYSOBJECTS?WHERE?NAME='IsMatch'?AND?XTYPE='FS')??
  • DROP?FUNCTION?IsMatch?
  • ?
  • --如果已經存在SqlCLR程序集則刪除該程序集?
  • IF?EXISTS(SELECT?*?FROM?SYS.ASSEMBLIES?WHERE?NAME='SqlCLR')??
  • DROP?ASSEMBLY?SqlCLR?
  • ?
  • --在SQL?Server中創建程序集,,創建的程序集名為SqlCLR?
  • CREATE?ASSEMBLY?SqlCLR?FROM?'F:\VS2008\netskycn\NetSkycn.Data\bin\Release\NetSkycn.Data.dll'?WITH?PERMISSION_SET?=?UNSAFE?
  • GO?
  • ?
  • --從CLR程序集中創建函數,函數名為IsMatch,有三個參數,?
  • --[SqlCLR]是SQL?Server中程序集名?
  • --[NetSkycn.Data.SqlCLR]是.NET中的類的全名(命名空間及類名)?
  • --[IsMatch]是.NET中類的函數名?
  • CREATE?FUNCTION?[dbo].[IsMatch]??
  • (??
  • @source?AS?NVARCHAR(200),?
  • @pattern?AS?NVARCHAR(200),?
  • @option?INT=3?
  • )??
  • RETURNS?BIT??
  • AS??
  • EXTERNAL?NAME?[SqlCLR].[NetSkycn.Data.SqlCLR].[IsMatch];??
  • GO?
  • ?
  • --從CLR程序集中創建函數,函數名為IsMatch,有三個參數,?
  • --[SqlCLR]是SQL?Server中程序集名?
  • --[NetSkycn.Data.SqlCLR]是.NET中的類的全名(命名空間及類名)?
  • --[SendMail]是.NET中類的函數名?
  • CREATE?PROCEDURE?[dbo].[SendMail]??
  • (??
  • @to?AS?NVARCHAR(200),?
  • @from?AS?NVARCHAR(200),?
  • @subject?AS?NVARCHAR(200),?
  • @body?AS?NVARCHAR(MAX),?
  • @userName?AS?NVARCHAR(200),?
  • @password?AS?NVARCHAR(200),?
  • @smtpHost?AS?NVARCHAR(200)?
  • )?
  • AS??
  • EXTERNAL?NAME?[SqlCLR].[NetSkycn.Data.SqlCLR].[SendMail];??
  • GO?

  • 如果沒有得到任何錯誤提示,則表示創建函數和存儲過程成功。至此我們會看到如下情形:


    這表示創建成功。
    測試創建函數的SQL語句(查找article表中title字段是3至5個字段的數據):

  • select?*?from?article?where?dbo.IsMatch(Title,'^[\u4e00-\u9fa5]{3,5}$',3)=1?

  • 測試創建存儲過程的SQL語句:

  • exec?[dbo].SendMail?@to='test@qq.com',@from='webmaster@qq.com',@subject='test',@body='This?mail?was?sent?by?SQL?Procedure',@userName='webmaster',@password='123',@smtpHost='smtp.qq.com'?

  • 以上代碼在SQL Server 2005中文企業版、SQL Server 2008英文企業版測試通過。
    可以看出在一些SQL語句不夠靈活的情況下,可以使用.NET來編寫存儲過程和函數,通過以上步驟之后和調用SQL語句寫的存儲過程和函數沒有區別,極大地方便了編程。

    周公
    2012-05-12

    ?

    總結

    以上是生活随笔為你收集整理的SQL Server中的CLR编程——用.NET为SQL Server编写存储过程和函数的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。