在 Visual Studio 和 SSMS 中调试存储过程
在 Visual Studio 和 SQL Server Management Studio 中调试存储过程。
引言
本文旨在演示如何使用与调试代码相同的技术从 Visual Studio 调试存储过程。为完整起见,本文还包含一个关于如何在 SQL Server Management Studio (SSMS) 中调试存储过程的部分。
文章分为两部分
使用 SQL Server Management Studio (SSMS) 调试存储过程
背景
有时,存储过程在从应用程序或报表调用时会返回意外的结果或生成错误。找出此类错误的根源可能是一项耗时的任务,尤其是在存储过程中的逻辑很复杂的情况下。一些遗留系统可能由数据库驱动,其中大部分业务逻辑都嵌入在存储过程中。在这种情况下,能够逆向工程大型存储过程以从根本上理解其行为和机制将非常有用。
本文的目的是提供一个清晰的示例,说明如何在 Visual Studio 和 SSMS 中调试存储过程。
流程
为了演示调试存储过程的过程,我们使用了一个包含要调试的存储过程的示例数据库。可以下载附加的脚本文件来创建文章中使用的数据库和对象。
创建数据库架构
表关系如下
- 一个用户可以属于多个组
- 一个组可以拥有多个用户
- 一个组可以拥有多个权限。
- 一个权限可以关联到多个组
简而言之,`User` 和 `Group` 之间存在多对多关系,此处使用名为 `UserGroup` 的连接表来实现。同样,`GroupPermisison` 表用于建立 `Group` 和 `Permisson` 表之间的多对多关系。
脚本执行后,数据库将包含以下表。
使用 Visual Studio 调试存储过程
为了调试存储过程,我们将使用附加的测试项目来逐步演示涉及的步骤。
此 Winforms 项目在 VS2013 中运行,尽管在某些早期版本中也应该可以运行。它接受来自 UI 的开始日期和结束日期。
单击“Debug Stored Proc”按钮后,单击事件中的代码将调用 `spGetActiveUserListByDateCreated`,并使用此示例中的 EF6 Code First 方法传递两个日期参数。
private void btTestDebug_Click(object sender, EventArgs e) { using (var context = new UsersContext()) { var startDate = new SqlParameter("@DateCreatedStart", dtStartDate.Text); var endDate = new SqlParameter("@DateCreatedEnd", dtEndDate.Text); var result = context.Database .SqlQuery<GridResult>("spGetActiveUserListByDateCreated @DateCreatedStart, @DateCreatedEnd", startDate, endDate) .ToList(); dgResults.DataSource = result; dgResults.Update();Application Debugging option appears in Server Explorer in VS 2010. In VS 2012 & VS2013 it appears in the SQL Server Object Explorer. } }
DataLayer 类库项目中的 POCO 类、DBContext 和 Mappings 的代码是使用 EF Power Tools 自动生成的。有关更多信息,请参阅文章使用 EF Power Tool 生成 POCO 类。
请注意,也可以使用您熟悉的任何其他数据访问方法来调用此过程,例如使用 EF Designer、Enterprise Library 或直接使用 ADO.NET。因此,上面的代码片段只是一个示例,将用于调用存储过程以触发调试器。
将返回指定日期范围内的用户列表。随后,结果将应用于 DataGridView 控件,如下所示。
为了调试 `spGetActiveUserListByDateCreated` 在生成此结果集时,需要在 Visual Studio 中的解决方案中应用以下设置。
1. 使用 Sql Server Object Explorer(VS2010 中的 Server Explorer)连接到 SQL Server
2. 双击 `spGetActiveUserListByDateCreated` 存储过程以在编辑器窗口中打开它。
3. 按 F9 在声明语句之后设置一个断点,如上所示。
4. 在 SQL Server Object Explorer 中,通过右键单击服务器并选择下面的选项来启用 `Application Debugging`。
请注意,`Application Debugging` 选项出现在 VS 2010 的 `Server Explorer` 中。在 VS 2012 和 VS 2013 中,它出现在 `SQL Server Object Explorer` 中,如上所示。
5. 在项目属性中启用 SQL Server 调试
在 `DebugProcTest` 的项目属性窗口中,选中 `Enable SQL Server Debugging` 复选框。
现在,生成并运行应用程序。
执行将在存储过程的断点处停止。
在此断点处,可以像在 Visual Studio 中调试 C# 或 VB.NET 代码一样,单步执行 T-SQL,即使用调试工具栏或调试快捷键。`spGetActiveUserListByDateCreated` 的内部工作将在下一节 SSMS 中进行调试。
本节结束了需要在 Visual Studio 项目中进行的更改,以便能够调试存储过程。
使用 SQL Server Management Studio (SSMS) 调试存储过程
在新查询窗口中粘贴以下 T-SQL
use Users declare @startdate datetime = '2014.01.01' declare @enddate datetime = convert( varchar(20), getdate(), 102 ) exec spGetActiveUserListByDateCreated @DateCreatedStart = @startdate ,@DateCreatedEnd = @enddate
这将把 `@startdate` 和 `@enddate` 传递给 `spGetActiveUserListByDateCreated`,并返回指定日期范围内活动用户的列表。上面的代码片段是调用测试过程和触发 SSMS 中的调试器的示例。
可以通过遵循以下简单步骤在 SSMS 中调试 `spGetActiveUserListByDateCreated`
1. 按 F9 在如下所示的位置设置断点。
2. 单击工具栏上的 Debug 按钮。
工具栏将发生变化,显示用于单步执行 T-SQL 的附加按钮。第一行上的黄色高亮显示表示窗口现在处于调试模式。
熟悉的调试按钮出现在工具栏上,与 Visual Studio 中的按钮类似。
继续 (Alt-F5) - 恢复执行直到下一个断点
停止调试 (Shift-F5)
进入 (F11) - 进入用户定义对象(如存储过程或函数)的内部主体
逐过程 (F10) - 前进到下一行,而不进入当前行
步出 (Shift+F11) - 返回调用例程或退出循环等。
3. 按 F10 键逐过程到 exec 命令,直到它被高亮显示为止,如上所示。
4. 按 F11 键进入 spGetActiveUserListByDateCreated。
spGetActiveUserListByDateCreated 的 T-SQL 将在查询窗口中自动打开,如上所示。
Locals 窗口显示了传递的两个日期参数的值。
5. 按 F10 或工具栏按钮 逐过程到 While 循环。
将鼠标图标放在 @id 变量上会显示其值,如上所示。
双击 @id 直到它被高亮显示,然后按 Shift-F9 键。这将显示快速监视窗口。
6. 按 F10 并进入 While 循环。
如前所述,可以在 Locals 窗口、快速监视窗口中使用变量,或者只需将鼠标悬停在变量上即可查看其值。SSMS 的一个限制是无法监视临时表的内容。
该循环从 User 表中获取 `firstname`、`surname`、`email` 和 `datecreated` 值,并将一行插入到一个临时表中。该循环将一直迭代,直到 User 表中的所有行都已插入到符合条件的临时表中。
如果有许多行需要循环,那么可以通过按 Shift+F11 键或单击步出按钮 来退出循环并继续执行循环外的代码。
一旦到达过程的末尾并执行了最后一个 `Select` 子句,控制将传递到调用窗口,结果将在那里返回,如上所示。
本节结束了如何在 SSMS 中调试存储过程的部分。
关注点
- Application Debugging 选项出现在 VS 2010 的 `Server Explorer` 中。在 VS 2012 和 VS 2013 中,它出现在 `SQL Server Object Explorer` 中。
- 在 SSMS 或 Visual Studio 中调试存储过程时,无法监视临时表的内容。
- 无法对视图执行调试。
结论
本文通过使用示例项目和数据库,演示了如何配置 Visual Studio 和 SSMS 以实现存储过程的调试。Visual Studio 中的调试尤其方便,因为可以看到从代码传递的确切参数值,并确定这些值是否符合预期。使用与调试 C# 或 VB.NET 相同的技术单步执行逻辑也很方便。
SSMS 中的调试适用于在应用程序或报表工具(如 SSRS 或 Crystal Reports)之外单独测试存储过程。通过传递测试参数值并单步执行代码,可以确定逻辑的正确性以及是否返回了预期的结果集。还可以通过传递无效参数来测试异常处理,并检查是否已正确处理。
熟悉这两种技术应该能够帮助开发人员快速确定错误或意外结果集的原因。