如何使用print语句调试存储过程?

Art*_*t F 34 t-sql sql-server stored-procedures

我正在尝试调试SQL Server Management Studio 2008中的存储过程.我想插入一些print语句来测试一些我知道错误的IF语句.

为了进行调试,我尝试使用该PRINT '5'命令.

我尝试过使用之RAISERROR类的'RAISERROR (N'Start',10,1) WITH NOWAIT'.

但这些没有显示任何打印输出,只显示结果集.消息刚才说1 row affected.

我试图像这样写代码(也许这是一个不正确的方法):

SET NOCOUNT ON         
RAISERROR (N'Start',10,1) WITH NOWAIT    
DECLARE @DocHandle INT        
DECLARE @PageSize INT, @PageIndex INT, @TOTL_CONT NUMERIC(5,0), @Paging BIT        
DECLARE @Type INT, @Search varchar(20) , @ORDE nVARCHAR(50), @SORT_ID nVARCHAR(50) 
DECLARE @CreatedOn varchar(25), @SystemGenerate bit   
Run Code Online (Sandbox Code Playgroud)

使用print语句调试存储过程的最佳方法是什么?

Kev*_*man 28

如果您正在使用MSSQL Server管理工作室,则打印语句将在"结果"选项卡下的"消息"选项卡下打印出来.

在此输入图像描述

打印语句将出现在那里.

  • mm,如上所述,我看到的唯一一件事是"1排受影响". (3认同)
  • 您是否尝试将print语句作为过程的第一行,以查看是否打印.可能是if语句没有像你期望的那样输入. (2认同)

cma*_*tin 14

以下是使用print语句的示例.它们应显示在消息选项卡下,如前一个人所示.

    Declare @TestVar int = 5;

    print 'this is a test message';
    print @TestVar;
    print 'test-' + Convert(varchar(50), @TestVar);
Run Code Online (Sandbox Code Playgroud)

打印消息


dys*_*oko 13

在我得到重复的答案之前; 我承认,我会在这里接受的唯一答案是这样的一个通过KM.以上.我拒绝投票给其他答案,因为他们都没有回答问题或他们不够.PRINT输出确实显示在消息窗口中,但这根本不是所要求的.

为什么在我的存储过程执行期间不显示PRINT语句输出?
这个答案的简短版本是你将你的sproc执行发送到SQL服务器,并且在完成整个事务之前它不会响应.这是一个位于此外部链接的更好答案.

  • 为了获得更大的意见/观察你的注意力集中在这个SO张贴在这里.
  • 具体看这个答案同一职位由Phil_factor的(呵呵!爱的SQL幽默)
  • 关于该使用WITH NOWAIT看RAISERROR的建议答案同一职位由JimCarden

不要做这些事情

  1. 有些人的印象是他们可以在PRINT语句后使用GO语句,但是你不能使用sproc的GO语句INSIDE.所以解决方案就出来了.
  2. 我不建议选择你的打印语句,因为它只会使你的结果集变得混乱,如果你的sproc应该稍后被程序使用,那么你将不得不知道在循环时要跳过哪些结果集通过数据阅读器的结果.这只是一个坏主意,所以不要这样做.
  3. SELECT-ING打印语句的另一个问题是它们并不总是立即显示.我对不同的执行方式有不同的经验,所以不要指望与这种方法有任何一致性.

在存储过程中替代PRINT
在我看来,这是一种狡猾的工作,因为语法在使用它的上下文中令人困惑,但谁知道它可能会在未来被Microsoft更新.我只是不喜欢提出错误的想法,唯一的目的是打印出调试信息......

看起来这个问题的唯一方法就是使用,正如已经多次解释过RAISERROR WITH NOWAIT.我提供了一个示例,并指出了这种方法的一个小问题:

ALTER
--CREATE 
    PROCEDURE [dbo].[PrintVsRaiseErrorSprocExample]
AS
BEGIN
    SET NOCOUNT ON;

    -- This will print immediately
    RAISERROR ('RE Start', 0, 1) WITH NOWAIT
    SELECT 1;

    -- Five second delay to simulate lengthy execution
    WAITFOR DELAY '00:00:05'

    -- This will print after the five second delay
    RAISERROR ('RE End', 0, 1) WITH NOWAIT
    SELECT 2;
END

GO

EXEC [dbo].[PrintVsRaiseErrorSprocExample]
Run Code Online (Sandbox Code Playgroud)

两个SELECT语句结果仅在执行完成后显示,并且print语句将按上面显示的顺序显示.

这种方法的潜在问题
假设你一个接一个地有你的PRINT语句和RAISERROR语句,然后它们都打印出来.我确定这与缓冲有关,但请注意,这可能会发生.

ALTER
--CREATE 
    PROCEDURE [dbo].[PrintVsRaiseErrorSprocExample2]
AS
BEGIN
    SET NOCOUNT ON;

    -- Both the PRINT and RAISERROR statements will show
    PRINT 'P Start';
    RAISERROR ('RE Start', 0, 1) WITH NOWAIT
    SELECT 1;

    WAITFOR DELAY '00:00:05'

    -- Both the PRINT and RAISERROR statements will show
    PRINT 'P End'
    RAISERROR ('RE End', 0, 1) WITH NOWAIT
    SELECT 2;
END

GO

EXEC [dbo].[PrintVsRaiseErrorSprocExample2]
Run Code Online (Sandbox Code Playgroud)

因此,这里的工作是,不要同时使用PRINT和RAISERROR,只选择一个而不是另一个.如果您希望在执行sproc期间显示输出,请使用RAISERROR WITH NOWAIT.

  • 外部链接不皱眉。仅仅依靠外部联系而本身没有实质性的答案是令人讨厌的。如果您提供外部链接以使人们获得更多详细信息,那实际上是一件好事。 (2认同)

KM.*_*KM. 11

尝试使用:

RAISERROR('your message here!!!',0,1) WITH NOWAIT
Run Code Online (Sandbox Code Playgroud)

您也可以尝试切换到"结果到文本",它只是默认工具栏上"执行"右侧的几个图标.

在上述两种情况下,您仍然看不到消息,请确保您正在运行与您正在编辑的过程相同的服务器/数据库/所有者版本.确保您正在执行RAISERROR命令,将其作为过程中的第一个命令.

如果所有其他方法都失败了,您可以创建一个表:

create table temp_log (RowID int identity(1,1) primary key not null
                      , MessageValue varchar(255))
Run Code Online (Sandbox Code Playgroud)

然后:

INSERT INTO temp_log VALUES ('Your message here')
Run Code Online (Sandbox Code Playgroud)

然后在运行程序(不提供回滚)之后只需select表.