我有一个带有int
输出参数的存储过程。如果我运行 SQL Server Profiler,通过一些 .Net 代码执行存储过程,并捕获 RPC:Completed 事件,TextData 如下所示:
declare @p1 int
set @p1=13
exec spStoredProcedure @OutParam=@p1 output
select @p1
为什么它看起来像是在执行存储过程之前获取了输出参数的值?
我有一个带有int
输出参数的存储过程。如果我运行 SQL Server Profiler,通过一些 .Net 代码执行存储过程,并捕获 RPC:Completed 事件,TextData 如下所示:
declare @p1 int
set @p1=13
exec spStoredProcedure @OutParam=@p1 output
select @p1
为什么它看起来像是在执行存储过程之前获取了输出参数的值?
RPC:Completed 事件类指示远程过程调用已完成。因此,此时输出参数实际上是已知的。查看跟踪 RPC:Started 是否显示了您的期望。
无论你怎么看,这都是一个错误。SQL Profiler“TextData”的目的是使人们能够理解和重复存储过程调用。在这种情况下,运行这个 T-SQL 可以给你一个完全不同的结果,如果spStoredProcedure
过程有任何依赖于@OutParam
参数输入值的逻辑,其中“13”的值作为输入值在某种程度上是有意义的。
很容易看出它有多方便(使您能够看到 proc 调用的输出值,否则这将需要与“RPC 输出参数”事件有关),但它实际上是一个关于 T 的“谎言” -SQL 等效已执行。
相关:我刚刚看到 Microsoft 客户服务和支持团队的一篇文章——关于另一种情况,将 RPC:Completed 事件的 BinaryData 转换为可显示的 TextData 值会导致原始 RPC 调用的再现不准确——这次代码页问题:
http://blogs.msdn.com/b/psssql/archive/2008/01/24/how-it-works-conversion-of-a-varchar-rpc-parameter-to-text-from-a-trace- trc-capture.aspx
更新:通过对此进行试验,我发现了该行为的另一个特点 - 如果 RPC 调用中该参数的输入值为Null
. 如果提供了非空值(并且 .Net SqlClient 中的参数具有方向“InputOutput”),则该初始 SET 保存真正的输入值,而不是结果输出值。但如果输入为空,则设置输出值。这一观察结果支持这样一种观点,即这只是分析器 RPC 到 TSQL 显示转换中的一个空处理错误。