如何调试 CLR 数据库对象
适用范围:SQL Server
SQL Server 支持调试数据库中的 Transact-SQL 和公共语言运行库 (CLR) 对象。 在 SQL Server 中进行调试的主要特点一个是易于设置和使用,另一个特点是 SQL Server 调试程序与 Microsoft Visual Studio 调试程序集成。 此外,还可以跨语言进行调试。 用户可以在 Transact-SQL 中无缝地单步执行 CLR 对象,反之亦然。 SQL Server Management Studio 中的 Transact-SQL 调试器无法用于调试托管数据库对象,但您可以通过使用 Visual Studio 中的调试器来调试这些对象。 Visual Studio 中的托管数据库对象调试支持所有常见的调试功能,例如,在服务器上执行的例程中的“单步执行”语句和“逐过程”语句。 调试器可以在调试过程中设置断点、检查调用堆栈、检查变量以及修改变量值。
注意
Visual Studio .NET 2003 无法用于 CLR 集成编程或调试。 SQL Server 包含预装的 .NET Framework,而 Visual Studio .NET 2003 无法使用 .NET Framework 2.0 程序集。
调试权限和限制
调试是一项需要高特权的操作,因此只允许 sysadmin 固定服务器角色成员在 SQL Server 中进行调试。
调试时存在下列限制:
调试 CLR 例程时仅限一次运行一个调试器实例。 存在此限制的原因是,所有 CLR 代码执行在命中断点时都会冻结,并且执行在调试器从断点继续运行之前不会继续。 但可以在其他连接中继续调试 Transact-SQL。 尽管 Transact-SQL 调试不会冻结服务器上的其他执行,但会因持有锁定而导致其他连接等待。
无法调试现有连接,只能调试新连接,因为 SQL Server 在建立连接之前需要有关客户端和调试程序环境的信息。
由于存在上述限制,建议在测试服务器上而不是在生产服务器上调试 Transact-SQL 和 CLR 代码。
概述
在 SQL Server 中进行的调试遵循单连接模式。 一个调试器只能检测和调试其附加到的客户端连接的活动。 由于调试器的功能不受连接类型的限制,因此表格格式数据流 (TDS) 和 HTTP 连接都可以进行调试。 不过,SQL Server 不允许调试现有连接。 调试支持在服务器上执行的例程中使用所有常见的调试功能。 调试程序与 SQL Server 之间的交互通过分布式组件对象模型 (COM) 进行。
有关调试托管存储过程、函数、触发器、用户定义类型和聚合的详细信息和场景,请参阅 Visual Studio 文档中的 SQL Server CLR 集成数据库调试。
必须对 SQL Server 实例启用 TCP/IP 网络协议,才能使用 Visual Studio 进行远程开发、调试和开发。 有关在服务器上启用 TCP/IP 协议的详细信息,请参阅 配置客户端协议。
调试步骤
按照以下步骤在 Microsoft Visual Studio 中调试 CLR 数据库对象:
打开 Microsoft Visual Studio,选择一个新的 SQL Server项目。 可以使用 Visual Studio 附带的 SQL LocalDB 实例。
创建新的 SQL CLR 类型 (C#):
- 在解决方案资源管理器中右键单击该项目,然后选择“添加”、“新建项...”。
- 在“添加新项”窗口中,选择“SQL CLR C# 存储过程”、“SQL CLR C# 用户定义函数”、“SQL CLR C# 用户定义类型”、“SQL CLR C# 触发器”、“SQL CLR C# 聚合”或“类”。
- 为新类型的源文件指定名称,然后选择“添加”。
将此新类型的代码添加到文本编辑器中。 有关示例存储过程的示例代码,请参阅本文后面的“示例”部分。
添加测试该类型的脚本:
- 在解决方案资源管理器中,右键单击该项目节点,然后选择“添加”“脚本...”。
- 在“添加新项”窗口中,选择“脚本(不在生成包中)”,并指定名称,例如
Test.sql
。 选择“添加”按钮。 - 在解决方案资源管理器中,双击
Test.sql
节点以打开默认测试脚本源文件。 - 将测试脚本(将会调用要调试的代码)添加到文本编辑器中。 有关示例脚本,请参阅下一节的示例。
将一个或多个断点放在源代码中。 在要调试的函数或例程上右键单击文本编辑器中的代码行。 选择“断点”、“插入断点”。 即会添加断点,并以红色突出显示该行代码。
在“调试”菜单中,选择“开始调试”以编译、部署和测试项目。 这时会运行
Test.sql
中的测试脚本,并调用托管数据库对象。如果在断点处出现黄色箭头(表示指令指针),代码执行将会暂停。 然后可以调试托管数据库对象:
- 使用“调试”菜单中的“单步切换”将指令指针前进到下一行代码。
- 使用“局部变量”窗口观察指令指针当前突出显示的对象状态。
- 将变量添加到“监视”窗口。 被监视变量的状态在整个调试会话过程中都可以进行观察,即使该变量并非指令指针当前突出显示的代码行时仍可。
- 从“调试”菜单中选择“继续”,以使指令指针前进到下一个断点或完成例程的执行(如果不再有其他断点)。
示例代码
下面的示例会将 SQL Server 版本返回给调用方。
using System.Data.SqlClient;
using Microsoft.SqlServer.Server;
public class StoredProcedures
{
[Microsoft.SqlServer.Server.SqlProcedure]
public static void GetVersion()
{
using (var connection = new SqlConnection("context connection=true"))
{
connection.Open();
var command = new SqlCommand("select @@version", connection);
SqlContext.Pipe.ExecuteAndSend(command);
}
}
}
示例测试脚本
以下测试脚本演示了如何调用在上一示例中定义的 GetVersion
存储过程。
EXEC GetVersion
后续步骤
有关使用 Visual Studio 调试托管代码的详细信息,请参阅 Visual Studio 文档中的 调试托管代码。
有关详细信息,请参阅 公共语言运行时 (CLR) 集成编程概念