本篇将用手工方式在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!");
}
}
}
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
with Permission_set = safe
说明:Permission_set为程序集的权限。SQLCLR有三种执行权限:
Safe:只能访问clr代码和数据库中的数据。不能访问非托管代码、外部资源和线程管理。
External_Access:可以访问外部系统,诸如文件系统、事件日志、网络和其它数据库服务器。不能访问非托管代码。
Unsafe:对访问对象不作任何限制。
修改程序集的执行权限需要有装饰数据库配置为Trustworthy。如果是数据库管理员不需要配置。配置方法如下:
--启用数据库的Trustworthy属性
use master
alter database northwind set trustworthy on
go
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
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
create procedure SayCsHi
as external Name CsProcs.[CsTestNamespace.CsTestClass].SayHi
go
说明:存储过程的外部名称采用的是程序集:类、方法 格式。由SqlServer无法识别命名空间和类,所以使用方括号([])将命名空间.类括起来让Sql Server知道,该括号中的内容代表类的完整路径。
--在SQL Server中执行存储过程查看结果。
exec SayCsHi
exec SayCsHi
这样一个完整的例子便完成了。
6、刷新程序集
程序集变更时,需要刷新程序集
alter assembly CsProcs from 'd:\SqlClr\HiCsWorld.dll'
7、查看所有程序及其权限
--查看已安装的程序集及其权限
select * from sys.assemblies
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;
}
/// 传递参数,用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
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
declare @Result nvarchar(100)
Exec GetCsGreeting 'Test',@result output
print @result
//Out 参数
declare @result nvarchar(100)
Exec GetCsGreetingOut 'TestOut',@result output
print @result
-----------------------------------------------------------------------
系列文章目录