`
380071587
  • 浏览: 447183 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

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

 
阅读更多

很早就知道可以用.NETSQLServer2005及以上版本编写存储过程、触发器和存储过程的,不过之前开发的系统要么因为历史原因用的是SQL2000要么根本用不着在SQLServer中启用CLR,所以一直没有尝试。最近因为项目的原因,在这方面做了一个调研,现在在这里分享一下心得。

首先要说明的是要在SQLServer中启用CLR必须是在SQLServer2005及以上版本,其次在默认情况下是没有启用CLR的,必须要显示设置为启用。比如我们要在ArticleCollectorDB数据库中运行用.NET编写的函数或者存储过程,至少先要进行下面的SQL语句:

exec sp_configure 'clr enabled', 1;--在SQL Server中启用CLR
reconfigure;
go
--在ArticleCollectorDB数据库中设置TRUSTWORTHY为ON
ALTER DATABASE [ArticleCollectorDB] SET TRUSTWORTHY ON

这时可能会得到提示要重新启动SQLServer,如果有此提示则重新启动一下。

接着我们在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,在这里要强调几点:一、对于将来提供给SQLServer调用的函数或者存储过程必须是静态方法,并且还必须带有SqlFunction或者SqlProcedure属性;二、对于一些需要访问外部网络资源和安全属性的还必须添加响应的属性(如本例中的SendMail方法,如果没有添加响应的属性在创建SQLFunction/Procedure时会出现错误提示)。

现在我们开始遵循先为SQLServer创建程序集、后创建函数或者存储过程的顺序来操作,在操作过程中用到的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字段是35个字段的数据):

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'

以上代码在SQLServer2005中文企业版、SQLServer2008英文企业版测试通过。

可以看出在一些SQL语句不够灵活的情况下,可以使用.NET来编写存储过程和函数,通过以上步骤之后和调用SQL语句写的存储过程和函数没有区别,极大地方便了编程。

周公

2012-05-12

分享到:
评论

相关推荐

    SQL CLR扩展DLL 在MS-SQL Server 环境中实现完整的文件、目录操作

    CLR扩展DLL 在MS-SQL Server 环境中实现文件、目录操作,程序使用VS2010编写,语言Vb.net。运行起来飞一般的感觉! 包含文件、目录操作的常用20多个函数,支持网络访问文件。 我经过5~6年的使用,实现用SQL管理复杂...

    SQL SERVER CLR 讲解及小例

    SQL SERVER CLR 的讲解,如果配置CLR,及一个CLR 库的文档 ,可以针对例子,编写自已的CLR 函数.

    用.NET为SQLServer编写存储过程和函数

    Server2005及以上版本编写存储过程、触发器和存储过程的,不过之前开发的系统要么因为历史原因用的是SQL2000要么根本用不着在SQL Server中启用CLR,所以一直没有尝试。最近因为项目的原因,在这方面做了一个调研,...

    在SQL Server中使用CLR调用.NET方法实现思路

    这使得开发人员可以用任何CLR语言(如C#、VB.NET或C++等)来写存储过程、触发器和用户自定义函数。我们如何实现这些功能呢? 为了使用CLR,我们需要做如下几步: 1、在.NET中新建一个类,并在这个类里新建一个...

    Microsoft SQL Server 2005技术内幕: T-SQ程序设计.pdf

    如基于集合的编程技术、日期和时间相关的XML和CLR数据类型的使用、临时对象、T-SQL和CLR用户自定义函数、存储过程、触发器、事务和新的错误处理结构、应用并发模型支持并发用户、使用Service Broker来控制数据库应用...

    SQLSERVER使用的CLR常用函数

    必须SQLSERVER2005以上,支持CLR函数才行。 其中Concatenate是拼接字符串的聚合函数,MaxOther是某列最大时获取另外一列值的聚合函数,MinOther则反之。 Regex开头的函数是正则相关的函数。GetCodeTable是拆分字符串...

    Microsoft SQL Server 2005 Express Edition SP3

    如果在更早 Community Technology Preview (CTP) 版本的 SQL Server Express 中禁用了 sp_configure 选项“SMO 和 DMO XP”,则在使用 SAVESYSDB 卸载该早期实例,然后使用 USESYSDB 安装本版本时,将可能无法从命令...

    SQL CLR扩展DLL,在SQL查询语句中直接存取文件,直接将数据变量读写到文件中。

    写了一个CLR 扩展DLL,在SQL 中直接读写文件的扩展函数。直接将数据变量读写到文件中。 程序使用VS2010编写,语言Vb.net。DLL只有几K大小,运行起来飞一般的感觉! 附件,包括VB.net源代码、安装(部署)T-SQL脚本、...

    如何使用SQL CLR表值函数进行扩展

    本文介绍了如何使用SQL Server中的表值函数来扩展SQL Server Reporting Services的数据访问功能。表值函数让编程人员和报表设计员有一定的灵活性,使他们能够实现数据不直接存储在数据库表中的报表制作场景。

    VS 2010+C# 扩展 SQL Server 2005/2008 CLR ,字符串聚合函数

    不管是SQL SERVER 2005还是SQL 2008 都没有提供字符串的聚合函数,但是 SQL 2005以后的版本支持CLR扩展系统的函数,所以就使用VS2010写了一个. 以后可以这样写了 select Age,dbo.joinstr(UserName,',',0) Name From ...

    SQL Server 2008数据库设计与实现

     8.3.1 存储过程和标量函数  8.3.2 对象内模拟  8.3.3 跨数据库边界  8.3.4 不同的服务器(分布式查询)  8.4 视图与表值函数  8.4.1 一般用法  8.4.2 使用视图实现可配置的行级安全  8.5 数据混淆 ...

    Visual.Basic.2010.&.NET4.高级编程(第6版)-文字版.pdf

    10.3.3 通过command对象使用存储过程 402 10.3.4 datareader对象 405 10.3.5 命令的异步执行 407 10.3.6 dataadapter对象 409 10.3.7 sql server .net数据提供程序 413 10.3.8 ole db .net数据提供程序 ...

    基于C#+CLR 技术创建一个Date转换函数for SQL Server

    基于C#+CLR 技术创建一个Date转换函数for SQL Server。

    SQL2005工作经验

    在SQL Server中使用CLR调用.NET方法; 函数的用法; 事务; 数据导入导出; 优化SQL Server的内存占用之执行缓存篇; 字符串的处理; exec sp_executesql @s与Exec(@s)的区别; SQL 2005新增的几...

    sql_clr调用c#生成数组函数

    sql_clr调用c#生成数组函数 sql数组是非常弱小的而C#非常强大,直接拿来用吧!

    SQL Server 中 EXEC 与 SP_EXECUTESQL 的区别.doc

    3、EXEC 执行纯动态SQL,执行时可能无法使用预编译的执行计划,关键是不安全,可以导致 SQL 注入 ,而 SP_EXECUTESQL 执行参数化动态 SQL ,执行时能使用预编译的执行计划,而且保存存储过程时就可以确定可以使用的预...

    SQLServer CLR实现Unicode URL 加解密,MD5不同编码加密

    因工作时常在SQLSERVER进行http接口操作,涉及编码的转换问题和中文MD5的加密问题,在数据库中根本无法实现,经研究可以借助CLR功能实现一下函数。 附件中提供了源码、开启CLR脚本及直接注册一下函数的脚本,无c#...

    解析SQL2005中如何使用CLR函数获取行号

    下面我先演示一下我实现的效果,先看测试语句——————————————————————————– 代码如下:exec BulkCopyToXls ‘select * from testTable’ , ‘d:/test’ , ‘testTable’ ,- 1 /* 开始导出...

    SQL SERVER 2012新增函数之字符串函数FORMAT详解

    本文主要介绍的是使用 FORMAT函数将日期/时间和数字值格式化为识别区域设置的字符串。下面话不多说,来看详细的介绍吧。 格式如下: format(value,format,culture) 第一个参数是要格式化的值,第二个是格式,第三...

Global site tag (gtag.js) - Google Analytics