如何在Sql Server(2008)中向存储过程添加跟踪/调试输出

Tim*_*ell 12 sql debugging sql-server-2008

能够将log4net样式调试信息添加到一组存储过程的最接近的是什么?一些程序将工作委托给其他程序,我希望从两者中获取跟踪信息.

我在开发时已经打印了print和select语句,理想情况下希望能够以不同的模式运行proc,具体取决于它是否是正常的故障排除操作并获得更多或更少的输出.

在这种特殊情况下,主存储过程将从代理作业重复运行,但可以在进行故障排除时从管理工作室运行.

procs已经使用错误日志表和电子邮件工具来捕获引发的错误.我希望能够跟踪的事情是输入数据问题意味着输出数据错误但是procs没有完全失败,并且确切地看到每个步骤完成了什么是有用的.

您知道什么方法可以产生有意义且理想的可过滤输出?

每个答案一个,所以我们可以看到最终的排名;-)

开箱即用的答案欢迎,例如"不要 - 在你需要的时候通过管理工作室"

Tim*_*ell 14

成堆的印刷声明

例如

print 'Doing something...'
INSERT INTO foo(a) VALUES(1)
print @@ROWCOUNT
Run Code Online (Sandbox Code Playgroud)

这个答案只是为了平衡,看到它在这里很安静.


Mar*_*ith 7

一种方法可能是检查是否从SSMS运行proc并激活一些自定义用户可配置的SQL Server Profiler事件(如果是).例如

CREATE PROC foo
AS
DECLARE @debug bit = CASE WHEN APP_NAME() = 'Microsoft SQL Server Management Studio - Query' 
                          THEN 1 
                          ELSE 0 END

DECLARE @userinfo nvarchar(128)
DECLARE @userdata varbinary(8000)

--Do some work here

IF @debug = 1
BEGIN
--Do some custom logging 
    SET @userinfo = N'Some custom info'
    SET @userdata = CAST('Some custom data' AS varbinary(8000))
    EXEC sp_trace_generateevent @eventid = 82 /*Use 82-91*/
                               ,@userinfo = @userinfo 
                               ,@userdata = @userdata

END
Run Code Online (Sandbox Code Playgroud)

虽然在实践中我通常使用类似下面的东西.有时会根据需要使用其他代码将消息(以及可能的步骤和状态值)记录到表中.这将允许满足"可过滤"的要求.

这会停止打印出来的消息,除非APP_NAME它指示它正在SSMS的英文版本中运行并使用,NOWAIT因此消息会立即打印出来而不是等待缓冲区填充.

CREATE PROCEDURE [dbo].[PrintMessage] @message            NVARCHAR(MAX),
                                      @PrependCurrentTime BIT = 0
AS
    IF APP_NAME() LIKE 'Microsoft SQL Server Management Studio%' 
      BEGIN
          DECLARE @CurrentTimeString VARCHAR(30);

          SET @CurrentTimeString = ''

          IF @PrependCurrentTime = 1
            BEGIN
                SET @CurrentTimeString = CONVERT(VARCHAR(19), GETDATE(), 20) + ' '
            END

          RAISERROR('%s%s',0,1,@CurrentTimeString,@message) WITH NOWAIT

      END
Run Code Online (Sandbox Code Playgroud)