在 SQL Server 2005 中创建托管对象






3.97/5 (19投票s)
2005年12月22日
7分钟阅读

87238
在 SQL Server 2005 中创建托管对象。
引言
SQL Server 2005 拥有许多出色的功能,使其在众多 SQL Server 版本中脱颖而出。这些功能包括 Service Broker(允许您在数据库中创建松耦合的 SOA 应用程序)、Notification Services(在特定事件发生时向订阅者发送通知)、安全增强功能(提供更精细的对象访问控制并避免一些常见的安全漏洞)。其中,最令人兴奋的功能之一是 CLR 与数据库引擎的集成。本文将通过一个小示例演示如何在 SQL Server 2005 中使用 CLR 以及如何创建托管对象。
CLR 语言与 T-SQL 对比
公共语言运行时 (CLR) 是每个 .NET 应用程序共享的运行时环境,它为 .NET 应用程序提供垃圾回收、线程支持、内存分配、代码访问安全等服务。它是 .NET Framework 的核心。现在,CLR 已集成到 SQL Server 2005(俗称 Yukon)中。这项功能使得可以使用 .NET 语言和 VS.NET 2005 来创建数据库对象,如触发器、用户定义函数和聚合函数。现在,您可以D3(开发、调试和部署)数据库对象。
CLR 与 SQL Server 2005 的集成迫使开发人员思考何时应该使用 C# 等 .NET 兼容语言,何时应该使用 T-SQL。T-SQL 拥有许多功能,自 Microsoft 早期版本 SQL Server (1988 年) 以来,它一直被用作访问和操作数据库的统一标准。这有什么问题吗?嗯,如果您仔细观察,您会发现您通常使用 T-SQL 以外的语言来开发 UI 和编程逻辑。其次,T-SQL 与 C# 等语言具有不同的编程模型。例如,如何在 T-SQL 中使用数组、集合、类和面向对象编程概念?尽管 T-SQL 有方法可以实现这些,但您需要了解 T-SQL 编程语句,并且需要大量代码才能完成通过 C# 可以轻松完成的任务。
CLR 具有许多优点,如安全性、类型安全、增强的编程模型等。如果我们深入分析,会发现 T-SQL 适合基于集合的操作,可能不如 C# 或 VB.NET 高效。.NET 语言利用了 Framework 类库的强大功能,使得在 C# 中进行操作比在 T-SQL 中更容易。例如,如何在 T-SQL 中分割字符串?在 C# 中,我们可以轻松地使用 System.String
类中的 split
函数来完成。因此,在 T-SQL 中需要多行代码才能完成的任务,在 C# 中只需几行代码即可轻松完成。需要考虑的一个主要问题是,代码应该放在哪里,是靠近服务器还是靠近客户端。现在使用 SQL Server 2005,您可以将 C# 代码放在客户端和服务器端,而 T-SQL 只能放在服务器端。
SQLAccess
您现在认为 SQL Server 2005 可以托管任何 .NET 代码吗?事实是您不能。您需要将代码编译成可以由 SQL Server 2005 托管的 DLL。其次,SQL Server 2005 无法处理多文件程序集,因此您需要创建一个单文件程序集。在我们深入研究代码之前,我想提一下,如果我们开发数据库对象,我们将引用 SQLAccess.dll,它用于以一种更优化的方式访问其他数据库相关对象。它包含一个名为 System.Data.SQLSever
的命名空间。它包含一些类,如 SQLContext
,通过它可以获取有关当前数据库、连接、触发器上下文等信息。SQLConnection
、SQLCommand
、SQLCommand
、SQLDataReader
的作用与 ADO.NET 2.0 中的作用相同。
.NET 代码在 SQL Server 2005 中的应用
以下是在 SQL Server 205 中使用 .NET 代码所需的步骤:
- 在 C# 中创建一个
static
函数/方法,位于某个类中。 - 将代码编译成 DLL 形式。
- 在 SQL Server 2005 中导入程序集,并为其指定一个名称。
- 创建存储过程、触发器、UDF,并通过给出您在步骤 3 中指定的名称以及命名空间和类来调用类中的方法。
.NET 中的方法
您可以创建任何 static
方法,并使用 SQLAccess.dll 中的类来使用数据库对象,并使用 .NET Framework 类来访问 BCL。假设您有兴趣创建一个存储过程。
using String;
public static class Split
{
public static void GetContacts()
{
SQLCommand com = SQLContext.GetCommand();
com.CommandText = " Select * from Customers";
com.CommandType = CommandType.Text;
SQLPipe p = new SQLPipe();
p.Send(com.ExecuteReader());
}
}
在 SQL Server 内部或外部编程 ADO.NET 之间存在一些差异。基本区别在于如何获取对象。因此,在上述示例中,我们不是直接实例化 Command 对象,而是使用一个名为 SqlContext
的辅助类来创建 Command。此外,当您获得 DataSet
或 DataReader
时,需要将其发送回执行存储过程的调用者。为此,我们有一个名为 SqlPipe
的类,可用于将结果发送回调用者。您还可以创建参数化存储过程,这将在下一个示例中进行演示。
public static class Split
{
public static void GetContacts(SQLString Customerid )
{
SQLCommand com = SQLContext.GetCommand();
com.CommandText = "Select * from Customers where Customerid = @id";
com.CommandType = CommandType.Text;
com.Parameters.Add("@id",SQLDbType.Char, 100).value= Customerid;
SQLPipe p = new SQLPipe();
p.Send(com.ExecuteReader());
}
}
在此代码中,我们只是从数据库中获取数据。第二步是编译代码。您可以使用 Visual Studio 2005 或通过命令行使用特定编译器来编译代码。正如我之前提到的,SQL Server 2005 只能托管 DLL,不能托管 EXE。因此,您不能在 SQL Server 2005 中托管 Windows 应用程序。将类编译成 DLL,假设命名为 splitter.dll,位于 c:\nishith 文件夹中。
导入程序集
第三步是在 SQL Server 中导入上述创建的程序集。导入有两种方式:
- 使用 SQL Server Management Studio。
- 使用新的 T-SQL 语句。
如果您想通过 SQL Server Management Studio 导入程序集,请在对象资源管理器中右键单击数据库的“可编程性”文件夹下的“程序集”文件夹,然后单击“新建程序集”。导入程序集的另一种方法是通过 CREATE ASSEMBLY 语句。
创建程序集 splitter
From 'c:\nishith\splitter.dll'
With Permission_set = SAFE
在此语句中,我们指定了程序集的名称,通过该名称它将在 SQL Server 对象中得到识别。该名称在存储过程、触发器等中指定。除了指定程序集名称外,您还必须指定程序集在 c:\nishith\splitter.dll 的位置。您可以指定 Permission_Set
,它告诉您的程序集可以做什么。它是否可以访问其他 .NET 资源甚至非托管资源?默认情况下,其 Permission_Set
值为 SAFE。其他选项是 EXTERNAL ACCESS 或 UNSAFE。执行上述语句后,SQL Server 会检查与您的程序集位于同一文件夹中的依赖项,如果缺少任何依赖项,CREATE ASSEMBLY 就会失败。如果您想列出 SQL Server 中的程序集,可以使用
Select * from sys.Assemblies
现在,如果您的 CREATE ASSEMBLY 语句成功执行,您就可以在任何存储过程、触发器或用户定义函数中使用它了。存储过程的定义将在 AS 子句之后发生变化。
Create Procedure Employee.GetData
as
EXTERNAL NAME Splitter.Split.GetContacts
调用托管代码时唯一需要指定的是 External Name 关键字,它告诉 SQL Server 引擎该方法是 SQL Server 外部的。如果在创建类时指定了命名空间,则需要包含命名空间作为完全限定名。创建存储过程后,您可以像使用其他存储过程一样使用它。
SQL Server 项目类型
Visual Studio 2005 提供了 SQL Server 项目类型,可以在 IDE 中进行开发、调试和部署。SQL Server 项目允许您使用预定义的模板创建托管对象,如触发器、存储过程,并使用基于属性的编程来实现。如果您查看引用,会找到 SqlAccess.Dll 的引用。Visual Studio 2005 会向 testScript 文件夹添加一个名为 Test.SQL 的文件。您需要额外做的就是使用位于 System.Data.SQL 文件夹中的适当属性来修饰类。例如,如果您正在创建存储过程,则您的方法应被 SQLProcedure
修饰。您可以在类中包含任意数量的存储过程。
public static class Split
{
[SQLProcedure]
public static void GetContacts()
{
SQLCommand com = SQLContext.GetCommand();
com.CommandText = " Select * from Customers";
com.CommandType = CommandType.Text;
SQLPipe p = new SQLPipe();
p.Send(com.ExecuteReader());
}
}
定义完成后,单击“生成”菜单中的“部署项目”以编译您的程序集并将其注册到 SQL Server 2005。Visual Studio 2005 实际上会运行 Test Script 文件夹中的 Tests.SQL 来注册对象。它在内部调用 Create Assembly 方法以在 SQL Server 2005 中注册托管对象。
祝您编码愉快!