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

时间:2022-02-25 02:04:21

原文: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 Server中的CLR编程——用.NET为SQL Server编写存储过程和函数

这表示创建成功。

测试创建函数的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编写存储过程和函数的更多相关文章

  1. 在SQL Server中使用CLR调用&period;NET方法

    介绍    我们一起来做个示例,在.NET中新建一个类,并在这个类里新建一个方法,然后在SQL Server中调用这个方法.按照微软所述,通过宿主 Microsoft .NET Framework 2 ...

  2. 在SQL Server中使用CLR调用&period;NET类库中的方法 &lpar;转载&rpar;

    在SQL Server中调用 .NET 类库的方法要分为下面几步来实现: 在.NET中新建一个类库项目,并在这个项目中添加一个类文件,并把要被SQL Server调用的方法定义为公有的,静态的方法. ...

  3. &lbrack;转载&rsqb;在SQL Server 中,如何实现DBF文件和SQL Server表之间的导入或者导出?

    原来使用SQL Server 2000数据库,通过DTS工具很方便地在SQL Server和DBF文件之间进行数据的导入和导出,现在安装了SQL Server2005之后,发现其提供的“SQL Ser ...

  4. SQL学习笔记七之MySQL视图、触发器、事务、存储过程、函数

    阅读目录 一 视图 二 触发器 三 事务 四 存储过程 五 函数 六 流程控制 一 视图 视图是一个虚拟表(非真实存在),其本质是[根据SQL语句获取动态的数据集,并为其命名],用户使用时只需使用[名 ...

  5. 转 在SQL Server中创建用户角色及授权&lpar;使用SQL语句&rpar;

     目录 要想成功访问 SQL Server 数据库中的数据 我们需要两个方面的授权 完整的代码示例 使用存储过程来完成用户创建 实例 要想成功访问 SQL Server 数据库中的数据, 我们需要两个 ...

  6. 【转】在SQL Server中创建用户角色及授权&lpar;使用SQL语句&rpar;

    1. 首先在 SQL Server 服务器级别,创建登陆帐户(create login) --创建登陆帐户(create login) create login dba with password=' ...

  7. Sql server 中关闭ID自增字段(SQL取消ID自动增长)

    sql server在导入数据的时候,有时候要考虑id不变,就要先取消自动增长再导入数据,导完后恢复自增. 比如网站改版从旧数据库导入新数据库,数据库结构不相同,可能会使用insert into xx ...

  8. 在SQL Server中创建用户角色及授权&lpar;使用SQL语句&rpar;

    1. 首先在 SQL Server 服务器级别,创建登陆帐户(create login) --创建登陆帐户(create login) create login dba with password=' ...

  9. SQL Server -&gt&semi;&gt&semi; CLR编程问题汇总

    1) CLR不支持C#类方法重载(Method Overload) 今天打算写个枚举目录的C# CLR存储过程,结果发现原来CLR不支持方法重载. Msg 6572, Level 16, State ...

随机推荐

  1. 【原】iOS学习之图片拉伸处理(类似qq的气泡)

    原理是拉伸里面的内容,将边保护起来 方法1: ①[image resizableImageWithCapInsets:UIEdgeInsetsMake(, , , )]; ②[image resiza ...

  2. CF 445A 简单DP

    今天早上找一道题的bug,还是找不出来,下午刷了几道水题,晚上准备回家的事, 然后本来想打CF的,一看,数学场,不打了. 这道题的题意: 给出一个序列,每次你可以从这个序列里面选择一个数ak,删除,然 ...

  3. java的控制流程

    1.顺序结构顺序结构就是指按语句执行的先后顺序,或者说语句出现的先后顺序逐条执行程序语句.语句块,完全是按照程序平台的执行约定进行的,比如第一个 HelloWorld程序:public class H ...

  4. jmeter IP欺骗功能实现

    使用过loadrunner的同学,应该都了解有个IP欺骗功能,jmeter遇到类似需求怎样实现呢? 环境:windows7,jdk1.8,jmeter3.1 使用IP欺骗功能前提是本地有多个可用IP, ...

  5. Struts2-在js中使用struts2标签

    1, 支行是下拉列表,自助银行也是下拉列表,它们是级联关系; <tr> <th width="17%"><span>*</span> ...

  6. Wireshark显示结果过滤基本语法

    按IP地址过滤:1.仅显示源地址为192.168.1.95的项目: ip.src eq 192.168.1.95 2.仅显示目的地址为192.168.1.95的项目: ip.dst eq 192.16 ...

  7. Echarts 一个开源图表设计工具

    一般来说,因有所需,方有所求.最近项目中有这方面的需求,用着感觉不错.特此记录!此处仅是一个简单的demo.官网地址:http://echarts.baidu.com/,相关文档.插件都有. 1.js ...

  8. Windows下虚拟机安装Mac OS X —– VMware Workstation12安装Mac OS X 10&period;11

    1下载  镜像:Instal OS X Yosemite 10.10.3(14D131).cdr        密码:qhhm 2 unlocker208文件(链接:https://pan.baidu ...

  9. Day 4-1 模块的导入方法和路径

    什么是模块? 在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护. 为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码 ...

  10. Python爬虫&lpar;四&rpar;——开封市58同城数据模型训练与检测

    前文参考: Python爬虫(一)——开封市58同城租房信息 Python爬虫(二)——对开封市58同城出租房数据进行分析 Python爬虫(三)——对豆瓣图书各模块评论数与评分图形化分析 数据的构建 ...