求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
  
 
 
     
   
分享到
用.NET为SQL Server编写存储过程和函数
 

作者:zhoufoxcn,发布于2012-5-25

 

很早就知道可以用.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语句写的存储过程和函数没有区别,极大地方便了编程。


相关文章 相关文档 相关视频



我们该如何设计数据库
数据库设计经验谈
数据库设计过程
数据库编程总结
数据库性能调优技巧
数据库性能调整
数据库性能优化讲座
数据库系统性能调优系列
高性能数据库设计与优化
高级数据库架构师
数据仓库和数据挖掘技术
Hadoop原理、部署与性能调优

 
分享到
 
 
     


MySQL索引背后的数据结构
MySQL性能调优与架构设计
SQL Server数据库备份与恢复
让数据库飞起来 10大DB2优化
oracle的临时表空间写满磁盘
数据库的跨平台设计
更多...   


并发、大容量、高性能数据库
高级数据库架构设计师
Hadoop原理与实践
Oracle 数据仓库
数据仓库和数据挖掘
Oracle数据库开发与管理


GE 区块链技术与实现培训
航天科工某子公司 Nodejs高级应用开发
中盛益华 卓越管理者必须具备的五项能力
某信息技术公司 Python培训
某博彩IT系统厂商 易用性测试与评估
中国邮储银行 测试成熟度模型集成(TMMI)
中物院 产品经理与产品管理
更多...