如何调试 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 数据库对象:

  1. 打开 Microsoft Visual Studio,选择一个新的 SQL Server项目。 可以使用 Visual Studio 附带的 SQL LocalDB 实例。

  2. 创建新的 SQL CLR 类型 (C#):

    1. 在解决方案资源管理器中右键单击该项目,然后选择“添加”、“新建项...”
    2. 在“添加新项”窗口中,选择“SQL CLR C# 存储过程”、“SQL CLR C# 用户定义函数”、“SQL CLR C# 用户定义类型”、“SQL CLR C# 触发器”、“SQL CLR C# 聚合”或“类”
    3. 为新类型的源文件指定名称,然后选择“添加”
  3. 将此新类型的代码添加到文本编辑器中。 有关示例存储过程的示例代码,请参阅本文后面的“示例”部分。

  4. 添加测试该类型的脚本:

    1. 在解决方案资源管理器中,右键单击该项目节点,然后选择“添加”“脚本...”
    2. 在“添加新项”窗口中,选择“脚本(不在生成包中)”,并指定名称,例如 Test.sql。 选择“添加”按钮。
    3. 在解决方案资源管理器中,双击 Test.sql 节点以打开默认测试脚本源文件
    4. 将测试脚本(将会调用要调试的代码)添加到文本编辑器中。 有关示例脚本,请参阅下一节的示例。
  5. 将一个或多个断点放在源代码中。 在要调试的函数或例程上右键单击文本编辑器中的代码行。 选择“断点”、“插入断点”。 即会添加断点,并以红色突出显示该行代码。

  6. 在“调试”菜单中,选择“开始调试”以编译、部署和测试项目。 这时会运行 Test.sql 中的测试脚本,并调用托管数据库对象。

  7. 如果在断点处出现黄色箭头(表示指令指针),代码执行将会暂停。 然后可以调试托管数据库对象:

    1. 使用“调试”菜单中的“单步切换”将指令指针前进到下一行代码
    2. 使用“局部变量”窗口观察指令指针当前突出显示的对象状态
    3. 将变量添加到“监视”窗口。 被监视变量的状态在整个调试会话过程中都可以进行观察,即使该变量并非指令指针当前突出显示的代码行时仍可。
    4. 从“调试”菜单中选择“继续”,以使指令指针前进到下一个断点或完成例程的执行(如果不再有其他断点)

示例代码

下面的示例会将 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) 集成编程概念