【问题标题】:Debugging queries inside stored procedures在存储过程中调试查询
【发布时间】:2012-11-14 16:30:29
【问题描述】:

考虑这个存储过程。程序的实际内容无关紧要,我只是为了示例而使用它:

CREATE PROCEDURE [dbo].[temp]
      @value1 varchar(50),
      @value2 varchar(50),
      @value3 varchar(50)
as      
begin
    Select *
    From valuesTable (nolock)
          inner join valuesTable2 RL (nolock)
                on (ValuesTable.ID = RL.RuleId and RL.Type = 'Something')     
    where @value1 = ValuesTable.RuleVal02
    and cast(@value2 as float) > cast(ValuesTable.RuleVal03 as float) and cast(@value2 as float) < cast(ValuesTable.RuleVal04 as float)
    --and (@value3 = ValuesTable.RuleVal05)
    and (@value3 = ValuesTable.RuleVal05 or ValuesTable.RuleVal05 = -1)
end

现在想象一下,这个(不是很复杂的功能)不起作用。我已经知道如何从 Visual Studio 和 SQL Server Management Studio 调试它,但是,这两种情况都缺乏:

这个函数的主要失败点是它执行的大查询。那么我想做的就是获取这个查询,将它复制到一个新的查询窗口并开始执行它并通过修改它的各个部分来调试它。

调试该查询的基本方法是将其复制到新的查询窗口,从执行代码中获取参数,然后手动将所有@variables 替换为其实际值。这行得通,但对我来说似乎是一项非常不必要的工作,理想情况下我想获取查询,因为它是在服务器上执行的 - 使用文字值而不是参数,例如:

where 'actualValue' = ValuesTable.RuleVal02
and cast(4.2 as float) > cast(ValuesTable.RuleVal03 as float) and cast(4.2 as float) < cast(ValuesTable.RuleVal04 as float)...

因为这听起来像是我只能通过分析器才能实现的东西,所以我启动了它。然后我将事件配置为捕获SP:StmtStarting 事件,以查看从存储过程执行的语句。然而,令我惊讶的是,我在分析器中看到的语句仍然显示它们的参数,而不是实际的文字值。

是否可以轻松复制在存储过程中执行的实际查询,并将参数替换为参数的字面值?探查器中是否有这样做的标志?还是有别的办法?

【问题讨论】:

  • 但是为什么要替换参数为实际值呢?你为什么不把参数声明部分变成DECLARE 语句,添加必要的赋值集并像那样运行脚本?
  • 嗯,这真的与所涉及的努力有关。如果我有一个复杂的 C++ 代码运行一个执行查询的 SP,那么我首先需要启动 SP 调试以获取传递给 SP 的值,然后使用 DECLARES 编写一个新查询并通过一些复制粘贴来启动这些值,然后只有这样我才能得到查询的结果。对于应该更简单的事情,这似乎需要做很多工作。

标签: sql-server sql-server-2008 debugging stored-procedures


【解决方案1】:

试试这个简单的工作流程(需要 5 秒):

  1. 运行 SSMS。
  2. 在对象资源管理器窗口中找到您的存储过程。
  3. 右键单击它以显示上下文菜单并从中选择“执行存储过程...”。
  4. 在显示的表格中设置所有参数值。
  5. SSMS 在新的查询选项卡中为您生成脚本(请参阅本答案末尾的脚本)。
  6. 保存此脚本以供进一步使用。
  7. 运行调试 -> 开始调试此脚本,然后单步执行 EXEC 语句。
  8. 更改参数值并运行下一次调试。
DECLARE @return_value int

EXEC    @return_value = [dbo].[temp]
        @value1 = N'1',
        @value2 = N'2',
        @value3 = N'3'

SELECT  'Return Value' = @return_value
GO

【讨论】:

    【解决方案2】:

    您可以在变量中编写查询,使用占位符而不是实际值,在运行时替换占位符并使用 sp_executesql 执行它

    显然,这只是您应该出于调试目的而不是在生产中做的事情;)

    这是一个例子:http://sqlfiddle.com/#!3/c8c43/5

    您的查询在变量内部填充了实际内容

    【讨论】:

    • 这是一个有趣的想法......但是,我真的不想将我的 SP 中的所有查询都变成动态的,这涉及到太多负面方面:sommarskog.se/dynamic_sql.html
    • 这就是为什么我说“仅用于调试目的”;)
    猜你喜欢
    • 2011-09-20
    • 2019-09-06
    • 2015-11-20
    • 2015-10-14
    • 1970-01-01
    • 1970-01-01
    • 2013-02-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多