如何调试 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 中的托管数据库对象调试支持所有常见的调试功能,例如,在服务器上执行的例程中的“单步执行”和“逐过程执行”语句。 调试器可以在调试过程中设置断点、检查调用堆栈、检查变量以及修改变量值。
调试权限和限制
调试是一项需要高特权的操作,因此只允许 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
中的测试脚本,并调用托管数据库对象。如果在断点处出现黄色箭头(表示指令指针),代码执行将会暂停。 然后可以调试托管数据库对象:
- 使用“调试”菜单中的“单步切换”将指令指针前进到下一行代码。
- 使用“局部变量”窗口观察指令指针当前突出显示的对象状态。
- 将变量添加到“监视”窗口。 可以在调试会话中观察监视变量的状态,即使变量不在指令指针当前突出显示的代码行中也是如此。
- 从“调试”菜单中选择“继续”,以使指令指针前进到下一个断点或完成例程的执行(如果不再有其他断点)。
示例代码
以下 C# 示例将 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
存储过程。
EXECUTE GetVersion;