SQL_Server_CLR全攻略.doc

上传人:hw****26 文档编号:3542905 上传时间:2019-06-03 格式:DOC 页数:27 大小:130.50KB
下载 相关 举报
SQL_Server_CLR全攻略.doc_第1页
第1页 / 共27页
SQL_Server_CLR全攻略.doc_第2页
第2页 / 共27页
SQL_Server_CLR全攻略.doc_第3页
第3页 / 共27页
SQL_Server_CLR全攻略.doc_第4页
第4页 / 共27页
SQL_Server_CLR全攻略.doc_第5页
第5页 / 共27页
点击查看更多>>
资源描述

1、SQL Server CLR 全攻略CLR 介绍和配置Microsoft SQL Server 现在具备与 Microsoft Windows .NET Framework 的公共语言运行时 (CLR) 组件集成的功能。CLR 为托管代码提供服务,例如跨语言集成、代码访问安全性、对象生存期管理以及调试和分析支持。对于 SQL Server 用户和应用程序开发人员来说,CLR 集成意味着您现在可以使用任何 .NET Framework 语言(包括 Microsoft Visual Basic .NET 和 Microsoft Visual C#)编写存储过程、触发器、用户定义类型、用户定义函数(

2、标量函数和表值函数)以及用户定义的聚合函数。 下面列出了这一集成的其中一些主要优点: 更好的编程模型。 改进了安全和安全性。 能够定义数据类型和聚合函数。 通过标准化环境简化了开发。 具备改善性能和可扩展性的潜力。 既然 CLR 这么灵活,那么我们如何在 T-SQL 和 CLR 之间做出选择呢?一般情况下,我们当以 T-SQL 为主,在下面几种情况下,应该考虑使用 CLR: SQL 中涉及大量的逻辑判断和逻辑运算。比如需要在数据库级别自定义加密算法,解密算法等。 T-SQL 无法处理需求。比如需要在 SQL 中进行正规表达式的判断等。 逻辑判断过于复杂,需要使用大量游标进行处理。这种情况一般要

3、进行测试,因为 CLR 不一定比游标快,关键是看你怎么写。下面介绍一下如何开启 CLR 和两种创建 CLR 的方法。关于如何在 VS 中编写 CLR 程序,请看后续章节。 开启 CLR。 在 SQL Server2005/2008 里面, CLR 默认是关闭的。可以使用如下 SQL 语句开启 CLR。 sp_configure show advanced options, 1; GO RECONFIGURE; GO sp_configure clr enabled, 1; GO RECONFIGURE; GO创建 CLR。 方法一:使用 DLL 文件进行创建 CREATE ASSEMBLY A

4、ssemblyName from DLLPath 例如:CREATE ASSEMBLY AssemblyName from c:hello.dll 方法二:使用文件 16 进制流进行创建 CREATE ASSEMBLY AssemblyName from 文件十六进制流 例如:CREATE ASSEMBLY AssemblyName from 0x123344 其中 0x12334是文件 c:hello.dll 的十六进制流。可以使用 UltraEdit 等编辑器把相关 dll文件的十六进制流 copy 出来。相比较,方法一简单,属于外部引用,通过创建就可以知道是哪个文件。但是 dll 文件路

5、径必须可以被 SQLServer 所访问,且部署时 dll 要随 SQLServer 变化而变化。 方法二是把流写进 SQLServer 中,从一定程度上屏蔽了代码。如果此 dll 不大的话,推荐使用方法二来创建 CLR。本文来自 CSDN 博客,转载请标明出处:http:/ 存储过程从这一节开始呢,我们就要开始 CLR 的编程之旅了。在这之前,我先把本节中需要了解的两个新类 SqlDataRecord 和 SqlMetaData,及五个新方法SqlContext.Pipe.SendResultsStart,SqlContext.Pipe.SendResultsRow,SqlContext.P

6、ipe.SendResultsEnd,SqlContext.Pipe.Send 和 SqlContext.Pipe.ExecuteAndSend 进行一下必要的说明,方便大家阅读后续的代码。首先 SqlDataRecord 和 SqlMetaData 是数据集合和原数据的意思。可以简单的把SqlDataRecord 理解成 DataTable,把 SqlMetaData 理解成 DataColumn。我们再向SqlDataRecord 里面填充数据之前要先执行 SqlContext.Pipe.SendResultStart()方法,告诉数据库下面开始填充数据,使用 SqlContext.Pip

7、e.SendResultRow 方法来填充数据,填充结束后使用 SqlContext.Pipe.SendResultEnd 方法来结束填充。这些都是基本流程,没什么好解释的,只要照着去做就可以了。SqlContext.Pipe.Send 是向客户端发送一条结果, SqlContext.Pipe.ExecuteAndSend 是执行一条语句。下面我将用几个实际的简单例子来说明如何使用这几个方法。1.使用 SqlContext.Pipe.Send 构建无参无返回值的存储过程 Microsoft.SqlServer.Server.SqlProcedure public static void USP

8、_SayHello() SqlContext.Pipe.Send(“USP:Hello TJVictor!“); 2.使用 SqlContext.Pipe.Send 构建带参无返回值的存储过程 Microsoft.SqlServer.Server.SqlProcedure public static void USP_SayHelloByParameter(SqlString msg) SqlContext.Pipe.Send(msg.ToString(); 3.使用 SqlContext.Pipe.Send 构建带参有返回值的存储过程 Microsoft.SqlServer.Server.S

9、qlProcedure public static SqlInt32 USP_SayHelloByReturn(SqlString msg) return msg.ToString().Length; 4.使用 SqlCommand 来执行语句,注意这里使用了 SQL Server 自带的 pubs 数据库 Microsoft.SqlServer.Server.SqlProcedure public static void USP_ExecuteBySqlCommand(SqlString stor_id, SqlString stor_name) /由于程序是在 SQL Server 内执行

10、,所以连接字符串写成“context connection=true“即可 using (SqlConnection con = new SqlConnection(“context connection=true“) con.Open(); SqlCommand com = new SqlCommand( string.Format(“insert into stores values(0,1)“, stor_id, stor_name), con); com.ExecuteNonQuery(); 5.使用 ExecuteAndSend 来执行语句,注意这里使用了 SQL Server 自带

11、的 pubs 数据库 Microsoft.SqlServer.Server.SqlProcedure public static void USP_ExecuteByExecuteAndSend(SqlString stor_id, SqlString stor_name) /由于程序是在 SQL Server 内执行,所以连接字符串写成“context connection=true“即可 using (SqlConnection con = new SqlConnection(“context connection=true“) con.Open(); SqlCommand com = n

12、ew SqlCommand( string.Format(“insert into stores values(0,1)“, stor_id, stor_name), con); SqlContext.Pipe.ExecuteAndSend(com); 4 和 5 的执行结果一样,但是在 CLR 中推荐使用方式 5,这是将结果返回到客户端的最高效方法,因为数据不必复制到托管内存即传输到网络缓冲区。6.使用 PipeSend 来发送单条记录 Microsoft.SqlServer.Server.SqlProcedure public static void UPS_PipeSendSqlData

13、Record() /像构造 Table 一样来构造 SqlDataRecord,其中 SqlMetaData 类似 DataColumn SqlDataRecord dataRecord = new SqlDataRecord(new SqlMetaData new SqlMetaData(“Col1“, SqlDbType.NVarChar,100), new SqlMetaData(“Col2“, SqlDbType.Int) ); for (int count = 1; count / 使用 SqlContext.Pipe.Send 构建无参无返回值的存储过程 / Microsoft.S

14、qlServer.Server.SqlProcedure public static void USP_SayHello() SqlContext.Pipe.Send(“USP:Hello TJVictor!“); / / 使用 SqlContext.Pipe.Send 构建带参无返回值的存储过程 / Microsoft.SqlServer.Server.SqlProcedure public static void USP_SayHelloByParameter(SqlString msg) SqlContext.Pipe.Send(msg.ToString(); / / 使用 SqlCon

15、text.Pipe.Send 构建带参有返回值的存储过程 / Microsoft.SqlServer.Server.SqlProcedure public static SqlInt32 USP_SayHelloByReturn(SqlString msg) return msg.ToString().Length; / / 使用 SqlCommand 来执行语句,注意这里使用了 SQL Server 自带的 pubs 数据库 / / Microsoft.SqlServer.Server.SqlProcedure public static void USP_ExecuteBySqlComma

16、nd(SqlString stor_id, SqlString stor_name) /由于程序是在 SQL Server 内执行,所以连接字符串写成“context connection=true“即可 using (SqlConnection con = new SqlConnection(“context connection=true“) con.Open(); SqlCommand com = new SqlCommand( string.Format(“insert into stores (stor_id,stor_name) values(0,1)“, stor_id, sto

17、r_name), con); com.ExecuteNonQuery(); / / 使用 ExecuteAndSend 来执行语句,注意这里使用了 SQL Server 自带的 pubs 数据库 / / Microsoft.SqlServer.Server.SqlProcedure public static void USP_ExecuteByExecuteAndSend(SqlString stor_id, SqlString stor_name) /由于程序是在 SQL Server 内执行,所以连接字符串写成“context connection=true“即可 using (SqlC

18、onnection con = new SqlConnection(“context connection=true“) con.Open(); SqlCommand com = new SqlCommand( string.Format(“insert into stores (stor_id,stor_name) values(0,1)“, stor_id, stor_name), con); SqlContext.Pipe.ExecuteAndSend(com); / / 使用 PipeSend 来发送单条记录 / Microsoft.SqlServer.Server.SqlProced

19、ure public static void UPS_PipeSendSqlDataRecord() /像构造 Table 一样来构造 SqlDataRecord,其中 SqlMetaData 类似 DataColumn SqlDataRecord dataRecord = new SqlDataRecord(new SqlMetaData new SqlMetaData(“Col1“, SqlDbType.NVarChar,100), new SqlMetaData(“Col2“, SqlDbType.Int) ); for (int count = 1; count / 使用 PipeSe

20、ndResult 来发送结果集 / Microsoft.SqlServer.Server.SqlProcedure public static void UPS_PipeSendResultSqlDataRecord() /像构造 Table 一样来构造 SqlDataRecord,其中 SqlMetaData 类似 DataColumn SqlDataRecord dataRecord = new SqlDataRecord(new SqlMetaData new SqlMetaData(“Col1“, SqlDbType.NVarChar,100), new SqlMetaData(“Co

21、l2“, SqlDbType.Int) ); /开始填充 SqlContext.Pipe.SendResultsStart(dataRecord); for (int count = 0; count 10; count+) /SqlDataRecord.SetString 类似 DataRow 的功能,像 Table 中填充值 dataRecord.SetString(0, count.ToString(); dataRecord.SetInt32(1, count); /通过 SendResultsRow 把数据填充到 Table,相关于 Table.Rows.Add(DataRow);

22、SqlContext.Pipe.SendResultsRow(dataRecord); /填充结束,返回结果集 SqlContext.Pipe.SendResultsEnd(); ; CLR 标量函数、表值函数和聚合函数(UDA)本节主要介绍使用 CLR 创建标量函数,表值函数和聚合函数。所谓标量函数指的就是此函数只返回一个值。表值函数返回值是一个表。聚合函数是在select 语句中使用的,用来聚合一个结果集,类似于 Sum()或是 Count()等内置的函数,而且真正的自定义聚合函数目前只能用 CLR 来实现。下面的例子使用了 SQLServer 自带的 pubs 数据库。1.CLR 标量函

23、数1.1 无参函数 / / 标量函数,不带参数 / / Microsoft.SqlServer.Server.SqlFunction( DataAccess = DataAccessKind.Read, IsDeterministic = true) public static SqlString UF_Scalar_SayHello() string returnValue = “null“; /由于程序是在 SQL Server 内执行,所以连接字符串写成“context connection=true“即可 using (SqlConnection conn = new SqlConne

24、ction(“context connection=true“) conn.Open(); SqlCommand com = new SqlCommand(“select top 1 au_lname from dbo.authors“,conn); using (SqlDataReader dr = com.ExecuteReader(CommandBehavior.CloseConnection) if (dr.Read() returnValue = dr.GetString(0);/返回 au_lname return returnValue;/返回“null ” CLR 函数用 Mi

25、crosoft.SqlServer.Server.SqlFunction 特征进行修饰。里面的参数含义为:DataAccess = DataAccessKind.Read 表示可访问数据表。关于 SqlFunctionAttribute 的属性将附录在文章的最后。/ / 标量函数,带参数 / / / Microsoft.SqlServer.Server.SqlFunction public static SqlString UF_Scalar_SayHelloByPar(SqlString par) return par; 2.CLR 表值函数表值与标量函数有些不同。因为要返回一个数据集合,所以一定要用一个填充数据的方法,在属性中用 FillRowMethodName 来表示,且返回值应该为 IEnumerable 类型。代码如下:1.首先自定义返回类型

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育教学资料库 > 精品笔记

Copyright © 2018-2021 Wenke99.com All rights reserved

工信部备案号浙ICP备20026746号-2  

公安局备案号:浙公网安备33038302330469号

本站为C2C交文档易平台,即用户上传的文档直接卖给下载用户,本站只是网络服务中间平台,所有原创文档下载所得归上传人所有,若您发现上传作品侵犯了您的权利,请立刻联系网站客服并提供证据,平台将在3个工作日内予以改正。