阿宽

Nothing is more powerful than habit!
  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

SQLCLR入门用法

Posted on 2011-02-22 14:05  宽田  阅读(865)  评论(0编辑  收藏  举报

 

本篇将用手工方式在SQL Server上调用程序集。

 

1、用VS建立一个类库,名为CsTestNamespace,并建立一个类CsTestClass。将CsTestClass改成成如下代码,主要是从SQL中返回一串内容。编译程序,将编译后程序更名为HiCsWorld.dll

using Microsoft.SqlServer.Server;

namespace CsTestNamespace
{
    
public class CsTestClass
    {
        
public static void SayHi()
        {
            SqlContext.Pipe.Send(
"Hi C# World from SQL Server!");
        }
    }
}

 

     说明:SqlContext称为“上下文”对象,此对象用于激活SQLCLR环境。Pipe属性用于将数据发送给客户。在SQL中,Print语句等价于Pipe.Send方法。应用程序通过获取SqlConnection对象InfoMessage集合中的数据,就可以访问要发送的数据。

 

2、在SQL Server上安装程序集。

create assembly CsProcs from 'd:\SqlClr\HiCsWorld.dll'
with Permission_set = safe

    说明:Permission_set为程序集的权限。SQLCLR有三种执行权限:

 

        Safe:只能访问clr代码和数据库中的数据。不能访问非托管代码、外部资源和线程管理。
        External_Access:可以访问外部系统,诸如文件系统、事件日志、网络和其它数据库服务器。不能访问非托管代码。
        Unsafe:对访问对象不作任何限制。

 

 3、修改程序集的执行权限

  修改程序集的执行权限需要有装饰数据库配置为Trustworthy。如果是数据库管理员不需要配置。配置方法如下:

--启用数据库的Trustworthy属性
use master
alter database northwind set trustworthy on
go

 

修改执行权限

--获得external_access权限
use master
grant external access assembly to [loginName]
go
--获得Unsafe权限
grant unsafe assembly to [loginName]
go

 

4、注册存储过程
    程序集中的方法注册为存储过程、函数等方可使用。现在我们注册为存储过程。
--注册存储过程
create procedure SayCsHi
as external Name CsProcs.[CsTestNamespace.CsTestClass].SayHi
go

    说明:存储过程的外部名称采用的是程序集:类、方法 格式。由SqlServer无法识别命名空间和类,所以使用方括号([])将命名空间.类括起来让Sql Server知道,该括号中的内容代表类的完整路径。

 

5、执行存储过程
--在SQL Server中执行存储过程查看结果。
exec SayCsHi

 这样一个完整的例子便完成了。

 

 

6、刷新程序集

    程序集变更时,需要刷新程序集

alter assembly CsProcs from 'd:\SqlClr\HiCsWorld.dll'

 

7、查看所有程序及其权限

--查看已安装的程序集及其权限
select * from sys.assemblies


8、增加传送参数方法

    上边的例子中并没有传送参数,现增加传递参数的方法。

    1)修改CsTestNamespace.CsTestClass。增加下边两个方法。

        /// <summary>
        
/// 传递参数,用ref返回结果
        
/// </summary>
        
/// <param name="name"></param>
        
/// <param name="greeting"></param>
        public static void GetGreeting(string name,ref string greeting)
        {
            greeting 
= "Hello from C#," + name;
        }

        
/// <summary>
        
/// 传递参数,用out返回结果
        
/// </summary>
        
/// <param name="name"></param>
        
/// <param name="greeting"></param>
        public static void GetGreetingOut(string name, out string greeting)
        {
            greeting 
= "Hello from C#," + name;
        }

 

    2)更新程序集

alter assembly CsProcs from 'd:\SqlClr\HiCsWorld.dll'


    3)将最新添加的两个方法注册为存储过程

--注册包含参数的C#存储过程(ref)
Create procedure GetCsGreeting
@name nvarchar(50),
@greeting nvarchar(100) output --输出结果
as External name CsProcs.[CsTestNamespace.CsTestClass].GetGreeting


--注册包含参数的C#存储过程(Out)
create procedure GetCsGreetingOut
@name nvarchar(50),
@greeting nvarchar(100) output
as External name CsProcs.[CsTestNamespace.CsTestClass].GetGreetingOut


     4)调用

//执行Ref参数
declare @Result nvarchar(100)
Exec GetCsGreeting 'Test',@result output
print @result

//Out 参数
declare @result nvarchar(100)
Exec GetCsGreetingOut 'TestOut',@result output
print @result