调试存储过程 (C#)

作者 :斯科特·米切尔

下载 PDF

Visual Studio Professional 和 Team System 版本允许设置断点并单步执行 SQL Server 中的存储过程,使调试存储过程与调试应用程序代码一样简单。 本教程演示存储过程的直接数据库调试和应用程序调试。

介绍

Visual Studio 提供丰富的调试体验。 通过几次击键或单击鼠标,可以使用断点停止执行程序并检查其状态和控制流。 Visual Studio 除了调试应用程序代码外,还支持从 SQL Server 中调试存储过程。 就像可以在 ASP.NET 代码隐藏类或业务逻辑层类的代码中设置断点一样,因此它们也可以放置在存储过程中。

在本教程中,我们将了解如何从 Visual Studio 中的服务器资源管理器进入存储过程,以及如何设置当从正在运行的 ASP.NET 应用程序调用存储过程时命中的断点。

注释

遗憾的是,存储过程只能通过 Visual Studio 的 Professional 和 Team Systems 版本介入和调试。 如果您使用 Visual Web 开发工具或 Visual Studio 的标准版本,欢迎阅读我们演示调试存储过程所需步骤的内容,然而,您将无法在自己的计算机上复制这些步骤。

SQL Server 调试概念

Microsoft SQL Server 2005 旨在提供与 公共语言运行时(CLR)的集成,这是所有 .NET 程序集使用的运行时。 因此,SQL Server 2005 支持托管数据库对象。 也就是说,可以在 C# 类中创建数据库对象,例如存储过程和 User-Defined Functions (UDF) 作为方法。 这使这些存储过程和 UDF 能够利用 .NET Framework 和你自己的自定义类中的功能。 当然,SQL Server 2005 还提供对 T-SQL 数据库对象的支持。

SQL Server 2005 为 T-SQL 和托管数据库对象提供调试支持。 但是,这些对象只能通过 Visual Studio 2005 Professional 和 Team Systems 版本进行调试。 在本教程中,我们将检查调试 T-SQL 数据库对象。 后续教程介绍如何调试托管数据库对象。

SQL Server 2005 CLR 集成团队的 SQL Server 2005 博客文章中的 T-SQL 和 CLR 调试概述重点介绍了从 Visual Studio 调试 SQL Server 2005 对象的三种方法:

  • 直接数据库调试 (DDD) - 从“服务器资源管理器”中,我们可以逐步进入任何 T-SQL 数据库对象,如存储过程和用户定义函数 (UDF)。 我们将在步骤 1 中检查 DDD。
  • 应用程序调试 - 我们可以在数据库对象中设置断点,然后运行 ASP.NET 应用程序。 执行数据库对象时,将触发断点并控制权转移到调试器。 请注意,在应用程序调试中,我们无法从应用程序代码单步进入数据库对象。 我们必须在希望调试器停止的那些存储过程或 UDF 中明确设置断点。 从步骤 2 开始进行应用程序调试。
  • 从 SQL Server 项目进行调试 - Visual Studio Professional 和 Team Systems 版本包括通常用于创建托管数据库对象的 SQL Server 项目类型。 我们将在下一教程中检查如何使用 SQL Server 项目并调试其内容。

Visual Studio 可以在本地和远程 SQL Server 实例上调试存储过程。 本地 SQL Server 实例是在 Visual Studio 所在的同一台计算机上安装的实例。 如果正在使用的 SQL Server 数据库未位于开发计算机上,则它被视为远程实例。 对于这些教程,我们一直在使用本地 SQL Server 实例。 在远程 SQL Server 实例上调试存储过程需要比在本地实例上调试存储过程时更多的配置步骤。

如果使用本地 SQL Server 实例,可以从步骤 1 开始,最后完成本教程。 但是,如果使用远程 SQL Server 实例,则首先需要确保在调试时使用远程实例上具有 SQL Server 登录名的 Windows 用户帐户登录到开发计算机。 此外,连接到数据库的此数据库登录名以及用于从正在运行的 ASP.NET 应用程序连接到数据库的登录名,必须是角色 sysadmin 的成员。 有关配置 Visual Studio 和 SQL Server 调试远程实例的详细信息,请参阅本教程末尾的“远程实例上的调试 T-SQL 数据库对象”部分。

最后,了解对 T-SQL 数据库对象的调试支持不像对 .NET 应用程序的调试支持那样功能丰富。 例如,不支持断点条件和筛选器,只有调试窗口的子集可用,不能使用“编辑并继续”,“即时”窗口呈现为无用窗口等。 有关详细信息,请参阅 调试器命令和功能的限制

步骤 1:直接进入存储过程

使用 Visual Studio 可以轻松直接调试数据库对象。 让我们看看如何使用“直接数据库调试(DDD)”功能单步执行 Northwind 数据库中的 Products_SelectByCategoryID 存储过程。 顾名思义,Products_SelectByCategoryID 返回某个特定类别的产品信息;它是在 类型化数据集的 TableAdapters 教程中使用现有存储过程创建的。 首先打开服务器浏览器,然后展开 Northwind 数据库节点。 接下来,向下钻取到“存储过程”文件夹,右键单击 Products_SelectByCategoryID 存储过程,然后从上下文菜单中选择“单步执行存储过程”选项。 这将启动调试器。

Products_SelectByCategoryID由于存储过程需要输入@CategoryID参数,因此需要提供此值。 输入 1,这将返回有关饮料的信息。

将数值 1 赋给<span 类= @CategoryID 参数" />

图 1:对 @CategoryID 参数使用值 1

提供参数的值 @CategoryID 后,将执行存储过程。 然而,调试器会在第一个语句上暂停执行,而不执行完整。 请注意页边距中的黄色箭头,这指示存储过程中的当前位置。 可以通过‘Watch’窗口或将鼠标悬停在存储过程中的参数名称上来查看和编辑参数值。

调试器已在存储过程的第一条语句上停止

图 2:调试器已在存储过程的第一条语句上停止(单击以查看全尺寸图像

若要逐条语句单步执行存储过程,请单击工具栏中的“单步执行”按钮或按 F10 键。 Products_SelectByCategoryID存储过程包含单个SELECT语句,因此按下 F10 将跳过该语句,并完成存储过程的执行。 存储过程完成后,其输出将显示在“输出”窗口中,调试器将终止。

注释

T-SQL 调试在语句级别进行;无法单步调试进入 SELECT 语句。

步骤 2:为应用程序调试配置网站

虽然直接从服务器资源管理器调试存储过程是方便的,但在很多情况下,我们更有兴趣在从 ASP.NET 应用程序调用存储过程时调试存储过程。 我们可以从 Visual Studio 中向存储过程添加断点,然后开始调试 ASP.NET 应用程序。 从应用程序调用带断点的存储过程时,执行将在断点处停止,我们可以查看和更改存储过程的参数值并逐步执行其语句,就像我们在步骤 1 中所做的一样。

在开始调试从应用程序调用的存储过程之前,我们需要指示 ASP.NET Web 应用程序与 SQL Server 调试器集成。 首先,右键单击解决方案资源管理器ASPNET_Data_Tutorial_74_CS()中的网站名称。 从上下文菜单中选择“属性页”选项,选择左侧的“开始选项”项,然后在“调试器”部分选中“SQL Server”复选框(请参阅图 3)。

在应用程序属性页中勾选 SQL Server 复选框

图 3:检查应用程序属性页中的 SQL Server 复选框(单击以查看全尺寸图像

此外,我们需要更新应用程序使用的数据库连接字符串,以便禁用连接池。 关闭与数据库的连接时,相应的 SqlConnection 对象将放置在可用连接的池中。 与数据库建立连接时,可以从此池中检索可用的连接对象,而无需创建和建立新连接。 此连接对象池是一个性能增强功能,并且默认启用。 但是,在调试时,我们希望关闭连接池,因为在处理从池中获取的连接时,调试基础结构未正确重新建立。

若要关闭连接池,请更新 NORTHWNDConnectionString 中的 Web.config ,使其包含设置 Pooling=false

<connectionStrings>
    <add name="NORTHWNDConnectionString" connectionString=
        "Data Source=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|\NORTHWND.MDF;
            Integrated Security=True;User Instance=True;Pooling=false"
        providerName="System.Data.SqlClient" />
</connectionStrings>

注释

通过 ASP.NET 应用程序完成 SQL Server 调试后,请务必通过从连接字符串中删除 Pooling 设置(或将其设置为 Pooling=true )来恢复连接池。

此时,ASP.NET 应用程序已配置为允许 Visual Studio 在通过 Web 应用程序调用时调试 SQL Server 数据库对象。 现在剩下的就是将断点添加到存储过程并开始调试!

步骤 3:添加断点和调试

打开Products_SelectByCategoryID存储过程,并在语句SELECT开头设置断点。操作方法是可以单击适当位置的边距,或者将光标放在语句SELECT开头,然后按 F9。 如图 4 所示,断点在边距中显示为红色圆圈。

在Products_SelectByCategoryID存储过程中设置断点

图 4:在 Products_SelectByCategoryID 存储过程中设置断点(单击以查看全尺寸图像

为了使 SQL 数据库对象通过客户端应用程序进行调试,必须将数据库配置为支持应用程序调试。 首次设置断点时,该设置应自动打开,但仔细检查一下是明智的。 右键单击 NORTHWND.MDF 服务器资源管理器中的节点。 上下文菜单应包含名为“应用程序调试”的选中菜单项。

确保已启用应用程序调试选项

图 5:确保启用应用程序调试选项

启用断点集和应用程序调试选项后,我们便可以从 ASP.NET 应用程序调用时调试存储过程。 通过转到“调试”菜单并选择“开始调试”、“按 F5”或单击工具栏中的绿色播放图标来启动调试器。 这将启动调试器并启动网站。

存储过程 Products_SelectByCategoryID 是在 使用现有存储过程的 Typed DataSet 的 TableAdapters 教程 中创建的。 其相应的网页 (~/AdvancedDAL/ExistingSprocs.aspx) 包含一个 GridView,用于显示此存储过程返回的结果。 通过浏览器访问此页面。 到达页面后,存储过程中的 Products_SelectByCategoryID 断点将被触发,随后会将控制权返回到 Visual Studio。 就像在步骤 1 中一样,可以单步执行存储过程的语句并查看和修改参数值。

ExistingSprocs.aspx页面最初会显示饮品

图 6ExistingSprocs.aspx 页面最初显示饮料(单击可查看全尺寸图像

已达到存储过程断点

图 7:已达到存储过程断点(单击以查看全尺寸图像

如图 7 所示,“监视”窗口中@CategoryID 参数的值为 1。 这是因为 ExistingSprocs.aspx 页面最初在饮料类别中显示产品,其 CategoryID 值为 1。 从下拉列表中选择不同的类别。 这样做会导致回发并重新执行 Products_SelectByCategoryID 存储过程。 再次命中断点,但这次@CategoryID参数的值反映了所选下拉列表项。CategoryID

从 Drop-Down 列表中选择其他类别

图 8:从 Drop-Down 列表中选择其他类别(单击以查看全尺寸图像

<span 类= @CategoryID 参数反映从网页中选择的类别“/>

图 9:参数 @CategoryID 反映从网页中选择的类别(单击以查看全尺寸图像

注释

如果在访问ExistingSprocs.aspx页面时未命中存储过程中的Products_SelectByCategoryID断点,请确保以下事项:在 ASP.NET 应用程序“属性”页的“调试器”部分中选中 SQL Server 复选框、禁用了连接池,并启用了数据库的应用程序调试选项。 如果仍遇到问题,请重启 Visual Studio 并重试。

在远程实例上调试 T-SQL 数据库对象

当 SQL Server 数据库实例与 Visual Studio 位于同一台计算机上时,通过 Visual Studio 调试数据库对象非常简单。 但是,如果 SQL Server 和 Visual Studio 位于不同的计算机上,则需要一些仔细的配置才能使一切正常工作。 我们面临两个核心任务:

  • 确保用于通过 ADO.NET 连接到数据库的登录名属于该 sysadmin 角色。
  • 确保开发计算机上 Visual Studio 使用的 Windows 用户帐户是属于 sysadmin 该角色的有效 SQL Server 登录帐户。

第一步相对简单。 首先,标识用于从 ASP.NET 应用程序连接到数据库的用户帐户,然后从 SQL Server Management Studio 将该登录帐户添加到 sysadmin 角色。

第二项任务要求用于调试应用程序的 Windows 用户帐户是远程数据库的有效登录名。 但是,你登录到工作站的 Windows 帐户可能不是 SQL Server 上的有效登录名。 最好选择将某些 Windows 用户帐户指定为 SQL Server 调试帐户,而不是将特定登录帐户添加到 SQL Server。 然后,若要调试远程 SQL Server 实例的数据库对象,请使用该 Windows 登录帐户的凭据运行 Visual Studio。

一个示例应该有助于澄清问题。 假设 Windows 域中有一个 Windows SQLDebug 帐户。 此帐户需要被添加到远程 SQL Server 实例中,作为有效的登录名,并且加入角色 sysadmin。 然后,若要从 Visual Studio 调试远程 SQL Server 实例,需要以用户身份 SQLDebug 运行 Visual Studio。 这可以通过退出工作站,重新以SQLDebug身份登录并启动 Visual Studio,但更简单的方法是用我们自己的凭据登录工作站,然后使用runas.exeSQLDebug用户身份启动 Visual Studio。 runas.exe 允许以不同用户帐户的身份执行特定应用程序。 若要以SQLDebug身份启动 Visual Studio,可以在命令行中输入以下语句:

runas.exe /user:SQLDebug "%PROGRAMFILES%\Microsoft Visual Studio 8\Common7\IDE\devenv.exe"

有关此过程的更详细说明,请参阅 William R. Vaughn 的《Visual Studio 和 SQL Server 入门指南(第七版)》Hitchhiker's Guide

注释

如果开发计算机正在运行 Windows XP Service Pack 2,则需要将 Internet 连接防火墙配置为允许远程调试。 作方法:启用 SQL Server 2005 调试 文章指出,这涉及两个步骤:(a)在 Visual Studio 主机上,必须添加到 Devenv.exe 异常列表并打开 TCP 135 端口;(b) 在远程 (SQL) 计算机上,必须打开 TCP 135 端口并添加到 sqlservr.exe 异常列表。 如果域策略要求通过 IPSec 进行网络通信,则必须打开 UDP 4500 和 UDP 500 端口。

概要

除了为 .NET 应用程序代码提供调试支持外,Visual Studio 还提供 SQL Server 2005 的各种调试选项。 在本教程中,我们了解了其中两个选项:直接数据库调试和应用程序调试。 若要直接调试 T-SQL 数据库对象,请通过服务器资源管理器找到该对象,然后右键单击它并选择“逐步进入”。 这会启动调试器,并在数据库对象中的第一条语句处停止。此时,您可以逐步执行对象的语句,查看并修改参数值。 在步骤 1 中,我们使用此方法进入 Products_SelectByCategoryID 存储过程。

应用程序调试允许直接在数据库对象中设置断点。 当从客户端应用程序(如 ASP.NET Web 应用程序)调用具有断点的数据库对象时,程序将在调试器接管时停止。 应用程序调试非常有用,因为它更清楚地显示了应用程序作导致调用特定数据库对象的原因。 但是,它需要比直接数据库调试更多的配置和设置。

还可以通过 SQL Server 项目调试数据库对象。 我们将在下一教程中了解如何使用 SQL Server 项目以及如何使用它们来创建和调试托管数据库对象。

快乐编程!

关于作者

斯科特·米切尔,七本 ASP/ASP.NET 书籍的作者和 4GuysFromRolla.com 的创始人,自1998年以来一直在与Microsoft Web 技术合作。 斯科特担任独立顾问、教练和作家。 他的最新书是《Sams Teach Yourself ASP.NET 2.0 in 24 Hours》。 可以通过 mitchell@4GuysFromRolla.com 联系到他。