使用 SQL Server Profiler(我在 SQL Server 2012 上),我试图生成一个有用的跟踪来显示参数值,而不仅仅是带有变量名的 SQL。存储过程遍历大量 Inventory 数据以生成一些非常有价值的结果,并且我正在尝试记录现有行为,因此我可以对其进行单元测试,准确定义它,然后将其重构为理智的东西。
我有一个执行 54 参数子过程的存储过程,在一个循环内,存储过程创建一个游标,然后执行一个 while 循环。这是一个简化的视图:
CREATE PROCEDURE
[dbo].[OuterProcedure]
( @ProductCode varchar(8),
-- 41 more parameters omitted
)
AS
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED
SET NOCOUNT ON
DECLARE @AboutFourHundredLocalvariables -- omit about 400 local variable declarations.
-- OMIT ABOUT 10 temporary table declarations.
DECLARE aCursor CURSOR FAST_FORWARD FOR
SELECT [ID],bkno, -- about 40 fields omitted.
FROM vwVeryComplexViewThatDoesALotOfVeryBrutalJoins
WHERE (about_80_boolean_expressions AND omitted_here)
ORDER BY some,keys,like,this
OPEN aCursor
FETCH NEXT FROM aCursor /* Get First Record */
INTO @ID, @about_40_fields,....
WHILE (@@FETCH_STATUS = 0) AND
( @About80MoreBooleanExpressionsHere)
BEGIN /* 1 */
-- about 700 lines of logic, math and if-parameter-this-then-that
-- stuff omitted
EXEC @ConsiderItem =
InnerProcedureCallWithinLoop
@from_locn,
@About53PARAMSOMITTED,
...
FETCH NEXT FROM CurInventory /* Get Next Record */
INTO @ID,@MoreStuff,...
END
CLOSE CurInventory
DEALLOCATE CurInventory
如何获得跟踪以显示传递给的所有参数值
InnerProcedureCallWithinLoop
?有 54 个参数。我是否必须在我的 SQL 中编写“54 行 debug-printfs”,或者我可以在执行 SQL 跟踪时转储过程调用的所有参数值吗?
当我现在得到一个跟踪时,我得到这个输出:
EXEC @ConsiderItem = InnerProcedureCallWithinLoop @from_locn,
@About53ParmsOmitted
我想知道的是,@from_locn = 1
等等@About53ParmsOmitted = 'hello world'
。
这并没有告诉我参数的实际值@from_locn
。在第一个参数的情况下,它被传递到我的顶级存储过程,所以我知道它是 0 或 1,视情况而定。然而,该内部过程中的 43 个参数中约有 40 个来自循环FETCH NEXT FROM aCursor
内的操作。WHILE
现在跟踪告诉我调用了多少次InnerProcedureCallWithinLoop
,每个调用了多长时间,但不是该调用的参数值是什么。如果我能以某种方式获得“可运行的独立 SQL 脚本”来复制我在代码中找到的一些极端情况,同时跟踪这些脚本,设置这些粗略的函数(我知道,54 个参数,这真的很粗略,但我没有写他们!)可能需要我一个小时的打字才能构建一个 SQL 脚本,让我自己调用这个极端情况,在这个庞大的 SQL Server 存储过程之外。
这是深入研究 SQL 表达式并构建可以探测这些复杂存储过程的脚本的全部努力的一部分。
更新我找到了 RPC“输出参数”记录选项,但没有找到“RPC IN PARAM”记录选项。
我硬着头皮告诉你,这样的痕迹是不能设置的,因为这不是痕迹的[感知]目的。我一直这样做:
如果我知道它只能从一个位置调用。否则,我在被调用者而不是调用者中执行此操作。
这显然与使用跟踪不同,后者能够捕获事件,即使它们开始但从未完成(错误参数、回滚事务)。如果这是您的问题,您需要查看 CLR 或电子邮件方法来外部化捕获的输出。