通过 Visual Studio 的 Professional 和 Team System 版本,我们可以对 SQL Server 中的存储过程设置断点并进入存储过程对其进行调试,这样我们可以象调试应用程序代码一样轻松地调试存储过程。本教程讲述对存储过程的两种调试方式:直接数据库调试和应用程序调试。
简介
Visual Studio 提供丰富的调试体验。我们只需按几个按键或点几下鼠标,就可以使用断点来中断程序的执行,检查程序的状态和控制流程。除了对应用程序代码的调试外,Visual Studio 还支持对SQL Server 内的存储过程的调试。正如可以在 的代码文件类或业务逻辑层的类的代码中设置断点一样,也可以在存储过程中设置断点。
本教程将介绍,怎样在 Visual Studio 中通过 Server Explorer 进入存储过程,以及怎样在其中设置断点,从而使我们运行的 应用程序在调用存储过程时能触发断点。
注意:遗憾的是,Visual Studio 只有Professional 和 Team Systems 两个版本可以进入和调试存储过程。如果您使用的是Visual Web Developer 或 Visual Studio 的标准版本,欢迎继续阅读下文以了解对存储过程进行调试所需的步骤,但在您自己的机器上无法执行这些步骤。
SQL Server 调试概念
Microsoft SQL Server 旨在实现与公共语言运行时 (CLR)的集成,CLR 是所有 .NET 汇编程序所使用的运行时环境。因此,SQL Server 支持托管数据库对象。也就是说,用户可以在Visual Basic 类中以方法的形式创建如存储过程和用户定义函数(UDF) 等数据库对象。这使得存储过程和 UDF 能够利用 .NET Framework 中以及定制类中的功能。当然,SQL Server 也支持 T-SQL 数据库对象。
SQL Server 支持对T-SQL 数据库对象和托管数据库对象的调试。但是只有Visual Studio Professional 版本和Team Systems 版本能够对这些对象的进行调试。本教程将详细介绍对T-SQL 数据库对象的调试。而对托管数据库对象的调试将在下一篇教程中讲述。
来自SQL Server CLR 集成团队的博客文章SQL Server 中的 T-SQL 和 CLR 调试概述重点讲述了以下三种通过Visual Studio 调试 SQL Server 对象的方法:
直接数据库调试(DDD):我们可以从 Server Explorer 进入 (step into) 任何 T-SQL 数据库对象,如存储过程及 UDF 。步骤 1 将详细介绍 DDD 。应用程序调试:我们可以在数据库对象中设置断点,然后运行 应用程序。当程序执行到含有断点的数据库对象时,会触发断点,并将程序控制权转交给调试器。注意,在使用应用程序调试方法时,我们不能从应用程序代码进入(step into) 数据库对象进行调试,而必须在要调试的存储过程或UDF 中直接设置断点,调试器将会在设置了断点的存储过程或UDF 处停顿。从步骤 2 开始将讲述应用程序调试方法。通过SQL Server项目调试:Visual Studio Professional 和 Team Systems 这两个版本均包含一个 SQL Server Project 类型,该类型常用于创建托管数据库对象。下一教程将详细介绍对SQL Server Project 的使用及对其内容的调试。
Visual Studio 既可以调试本地又可以调试远程SQL Server 实例中的存储过程。本地 SQL Server 实例就是与Visual Studio 安装在同一台机器上的实例。如果当前使用的SQL Server 数据库不在您的开发机器上,则为远程实例。我们的教程一直都是使用的本地SQL Server 实例。比起对本地实例中的存储过程进行调试,对远程SQL server 实例中的存储过程进行调试需要更多的配置步骤。
如果您使用的是本地 SQL Server 实例,则可以从步骤 1 开始一直进行到本教程最后一步。但如果您使用的是远程SQL Server 实例,在调试时,首先要确保您登录开发机器时使用的Windows 用户帐户在远程实例上相应地有一个SQL Server 登录帐户。此外,此数据库登录帐户和从运行的 应用程序连接到数据库时使用的数据库登录帐户都必须是sysadmin 角色的成员。关于配置 Visual Studio 和 SQL Server 以调试远程实例的详细信息,请参见本教程末尾的“调试远程实例中的T-SQL 数据库对象”部分。
最后,应知道对 T-SQL 数据库对象的调试功能不象对 .NET 应用程序的调试功能那样丰富。例如,不支持断点条件和断点过滤器、只能使用一部分调试窗口、不能使用Edit 和 Continue ,呈现的Immediate 窗口无用,等等。详情参见调试器命令和功能限制。
步骤1:直接进入存储过程
通过Visual Studio ,我们可以容易地直接调试数据库对象。我们来看看如何使用直接数据库调试(DDD ,Direct Database Debugging )功能进入 Northwind 数据库中的 Products_SelectByCategoryID 存储过程。顾名思义,Products_SelectByCategoryID 用于返回特定分类的产品信息。它是在对强类型 DataSet的 TableAdapter使用现有存储过程 教程中创建的。首先进入 Server Explorer 并展开Northwind 数据库节点。然后向下展开到 Stored Procedures 文件夹,右键单击 Products_SelectByCategoryID 存储过程,从关联菜单中选择 "Step Into Stored Procedure" 选项。此时调试器会启动。
由于Products_SelectByCategoryID 存储过程准备接受 @CategoryID 输入参数,系统会提示我们输入此值。输入1 ,这将返回饮料类产品的信息。
图1 :输入 1 作为 @CategoryID 参数值
提供@CategoryID 参数值后,会执行该存储过程。调试器执行完第一条语句就停止,而不是执行到过程结束。注意边框处出现的黄色箭头,它指示在存储过程中的当前位置。可以通过Watch 窗口或将鼠标停留在存储过程中的参数名称上查看和编辑参数值。
图2 :调试器在存储过程的第一条语句处停止
如要将存储过程当作一条语句一次跳过,单击工具箱中的Step Over 按钮或按下F10 。Products_SelectByCategoryID 存储过程包含一条 SELECT 语句,因此按下 F10 将跳过此语句并完成该存储过程的执行。存储过程执行完成后,其输出将显示在Output 窗口中,调试器将终止。
注意:T-SQL 调试在语句一级进行,因此不能进入 SELECT 语句。
步骤2:配置网站进行应用程序调试
虽然通过 Server Explorer 直接调试存储过程非常方便,但很多时候我们更想在我们的 应用程序调用存储过程时对其进行调试。我们可以从Visual Studio 中向存储过程添加断点,然后开始调试 应用程序。当应用程序调用带有断点的存储过程时,程序的执行会在断点处暂停,此时,我们可以查看并更改存储过程的参数值,逐步地调试其各条语句,就像我们在步骤1 中所做的那样。
在我们可以对应用程序调用的存储过程进行调试之前,首先要指示 web 应用程序与SQL Server 调试器相集成。首先,在 Solution Explorer 中右键单击网站名称(ASPNET_Data_Tutorial_74_VB) 。从关联菜单中选择 Property Pages 选项,然后选择左侧的Start Options 条目,选中 Debuggers 区域的 SQL Server 复选框(参见图 3 )。
图3 :在应用程序的 Property Pages 上选中 SQL Server 复选框
此外,我们还需要更新应用程序使用的数据库连接字符串以禁用连接池。当某个数据库连接关闭时,相应的SqlConnection 对象将被放入到一个包含可用连接的池中。当建立一个数据库连接时,则可从这个池中检索到一个可用的连接对象,而无需创建并建立一个新的连接。连接对象的这种缓冲池功能提高了性能,该功能缺省情况下是开启的。但在调试时,我们要关闭连接池,其原因是,如果使用从该池中得到的连接,则不能正确重建调试的基础架构。
为了禁用连接池,更改Web.config 文件中的 NORTHWNDConnectionString ,使其包含 Pooling=false 设置。
Copy Code
<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>
注意:通过 应用程序完成SQL Server 调试后,请务必恢复连接池功能,方法是,删除连接字符串中的Pooling 设置(或将其设置为 Pooling=true )。
现在已完成 应用程序配置,允许 Visual Studio 在 web 应用程序调用 SQL Server 数据库对象时对数据库对象进行调试。剩下的就是向存储过程添加断点并开始调试了!
步骤3:添加断点并调试
打开Products_SelectByCategoryID 存储过程,在 SELECT 语句的开头设置一个断点。方法是,单击边框处恰当位置或将光标移到SELECT 语句开始处并按下 F9 。如图 4 所示,断点显示为空白处的一个红色圆圈。
图4 :在 Products_SelectByCategoryID 存储过程中设置断点
为了通过客户端应用程序调试 SQL 数据库对象,必须将该数据库配置为支持应用程序调试。第一次设置断点时,此设置应会自动打开。但为谨慎起见,最好对此核实。在Server Explorer 中右键单击 NORTHWND.MDF 节点。关联菜单中的 Application Debugging 菜单项应处于选中状态。
图5 :确保 Application Debugging 选项已启用
设置了断点并启用了 Application Debugging 选项后,就可以调试从 应用程序调用的存储过程了。启动调试器:打开Debug 菜单并选择 Start Debugging ,或者按下F5 ,或者单击工具栏中的绿色 play 图标。此时,调试器启动,网站打开。
Products_SelectByCategoryID 存储过程是在对强类型 DataSet的 TableAdapter使用现有存储过程教程中创建的。其相应的 web 页面 (~/AdvancedDAL/ExistingSprocs.aspx) 包含一个 GridView 控件,以显示该存储过程返回的结果。通过浏览器访问该页面。打开页面后,Products_SelectByCategoryID 存储过程中的断点将被触发,程序控制权返回给Visual Studio 。如步骤 1 一样,您可以逐步调试存储过程的各条语句、查看并更改参数值。
图6 :ExistingSprocs.aspx 页面最初显示饮料类产品
图7 :执行到存储过程的断点
在图7 的Watch 窗口中可以看到,@CategoryID 参数的值为 1 。这是由于 ExistingSprocs.aspx 页面最初显示饮料类产品,而该类产品的CategoryID 值为 1 。从下拉列表中选择另一个分类。这将导致一次回传,并重新执行Products_SelectByCategoryID 存储过程。断点再次被触发,但这次 @CategoryID 参数的值反映的是所选下拉列表项的 CategoryID 。
图8 :从下拉列表中选择另一个分类
图9 :@CategoryID 参数反映 Web 页面上选择的分类
注意:如果访问 ExistingSprocs.aspx 页面时没有触发 Products_SelectByCategoryID 存储过程中的断点,请确保 应用程序的Properties Page 中 Debuggers 区域的SQL Server 复选框是选中的,连接池已禁用,并且数据库的Application Debugging 选项是启用的。如果还有问题,请重启Visual Studio 后重试。
调试远程实例中的T-SQL 数据库对象
若SQL Server 数据库实例与 Visual Studio 在同一台机器上,则通过Visual Studio 调试数据库对象相当简单。但如果 SQL Server 与Visual Studio 位于不同的机器上,则需要进行仔细配置以使各方面工作正常。为此我们的两个重要任务是:
确保通过 连接到数据库时使用的登录帐户具有 系统管理员 (sysadmin) 的身份。确保在开发机器上 Visual Studio 使用的 Windows 用户帐户是一个有效的、具有 sysadmin 身份的 SQL Server 登录帐户。
第一步相对简单。首先,确定使用哪个用户帐户来从 应用程序连接到数据库,然后通过SQL Server Management Studio 将此登录帐户添加到 sysadmin 角色中。
第二个任务要求您在调试应用程序时所使用的Windows 用户帐户是远程数据库上的一个有效的登录帐户。但有时您登录到工作站的Windows 帐户并非SQL Server 上的一个有效登录帐户。比起将您的特定登录帐户添加到SQL Server 来,一个更好的办法是将某个Windows 用户帐户指定为 SQL Server 调试帐户。然后,可以使用该Windows 登录帐户的证书运行 Visual Studio ,以便调试远程SQL Server 实例的数据库对象。
下面用一个例子来说明上述情况。假设Windows 域中有一个名为 SQLDebug 的Windows 帐户。需要将此帐户添加到远程 SQL Server 实例中,使其作为一个有效登录帐户及sysadmin 角色的一个成员。然后,我们需要以 SQLDebug 用户身份运行 Visual Studio ,以便通过 Visual Studio 调试远程 SQL Server 实例。这可以通过如下步骤完成:从工作站退出,用SQLDebug 帐户重新登录,然后启动 Visual Studio 。但一个更简单的方法是用我们自己的证书登录工作站,然后使用runas.exe 作为 SQLDebug 用户启动Visual Studio 。利用runas.exe ,可以借其他用户帐户的身份执行特定的应用程序。要作为SQLDebug 用户来启动Visual Studio ,可以命令行输入以下命令:
runas.exe /user:SQLDebug "%PROGRAMFILES%\Microsoft Visual Studio 8\Common7\IDE\devenv.exe"
关于该过程的更详细的介绍,请参见William R. Vaughn的 Hitchhiker’s Guide to Visual Studio and SQL Server, Seventh Edition ,以及怎样为调试设置 SQL Server 权限。
注意:如果您的开发机器运行的是 Windows XP Service Pack 2 ,您将需要配置Internet Connection Firewall 以允许远程调试。文章怎样启用 SQL Server 调试中提到这一过程包含两个步骤:“(a) 在Visual Studio 宿主机器上,必须向 Exceptions 列表添加 Devenv.exe ,并打开 TCP 135 端口;(b) 在远程 (SQL ) 机器上,必须打开TCP 135 端口并向 Exceptions 列表添加 sqlservr.exe 。如果您的域策略要求通过IPSec 进行网络通信,则必须打开 UDP 4500 和 UDP 500 端口。
小结
除了支持 .NET 应用程序代码的调试,Visual Studio 还为 SQL Server 提供了多种可选的调试方法。本教程中我们学习了其中两种方法:直接数据库调试和应用程序调试。要直接调试一个T-SQL 数据库对象,先通过Server Explorer 找到该对象,右键单击该对象,然后选择"Step Into…" 。此时,调试器会启动,并在该数据库对象的第一条语句处暂停。这时您可以逐步调试该对象的各条语句,查看并更改参数值。在步骤1 中我们使用了这种方法来进入 Products_SelectByCategoryID 存储过程进行调试。
应用程序调试允许直接在数据库对象中设置断点。当从客户端应用程序(如一个 web 应用程序)调用含有断点的数据库对象时,程序会暂停,调试器会接管程序的控制权。应用程序调试方法非常有用,原因是,它可以更清楚地展示对特定数据库对象的调用是由哪个应用程序操作引起的。但是,比起直接数据库调试方法,它需要进行较多的配置和设置。
我们还可通过 SQL Server Project 来对数据库对象进行调试。我们将在下一篇教程中看到对SQL Server Project 的使用,该教程将会讲述怎样使用SQL Server Project 来创建并调试托管数据库对象。