50

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

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

我尝试使用RAISERRORlike '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   

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

4

5 回答 5

39

如果您使用的是 Microsoft SQL Server Management Studio (SSMS),打印语句将在“消息”选项卡下打印出来,而不是在“结果”选项卡下。

在此处输入图像描述

打印语句将出现在那里。

于 2013-03-14T15:19:20.433 回答
21

这是打印语句使用的示例。他们应该像以前的人所指出的那样出现在消息选项卡下。

Declare @TestVar int = 5;

print 'this is a test message';
print @TestVar;
print 'test-' + Convert(varchar(50), @TestVar);

打印信息

于 2015-05-28T20:02:06.690 回答
19

在我得到我重申的答案之前;我承认我在这里接受的唯一答案是KM这个答案。以上。我对其他答案投了反对票,因为他们都没有真正回答所提出的问题,或者他们不够充分。PRINT 输出确实显示在消息窗口中,但这根本不是所要求的。

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

  • 如需更多意见/观察,请将您的注意力集中在此 SO 帖子
  • 具体看Phil_factor同一篇文章的这个答案(哈哈!喜欢SQL幽默)
  • 关于使用 RAISERROR WITH NOWAIT 的建议,请查看JimCarden对同一篇文章的回答

不要做这些事

  1. 有些人的印象是他们可以在 PRINT 语句之后使用 GO 语句,但不能在 sproc 的内部使用 GO 语句。所以这个解决方案就出来了。
  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]

两个 SELECT 语句的结果只会在执行完成后显示,打印语句将按上面显示的顺序显示。

这种方法的潜在问题
假设您有一个接一个的 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]

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

于 2016-06-01T21:45:18.060 回答
15

尝试使用:

RAISERROR('your message here!!!',0,1) WITH NOWAIT

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

上述两项都已到位,如果您仍然看不到消息,请确保您正在运行与您正在编辑的过程相同的服务器/数据库/所有者版本。确保您正在点击 RAISERROR 命令,使其成为过程中的第一个命令。

如果一切都失败了,您可以创建一个表:

create table temp_log (RowID int identity(1,1) primary key not null
                      , MessageValue varchar(255))

然后:

INSERT INTO temp_log VALUES ('Your message here')

然后在运行过程之后(提供没有回滚),只是select表。

于 2013-03-14T15:40:36.213 回答
0

查看 MSDN 文档中的这个 Howto:运行 Transact-SQL 调试器- 它不是使用 PRINT 语句,但它可能有助于您调试代码。

此 YouTube 视频:SQL Server 2008 T-SQL 调试器展示了调试器的使用。

=> 存储过程是用Transact-SQL编写的。这允许您调试所有 Transact-SQL 代码,因此它就像在 Visual Studio 中通过定义断点和观察变量进行调试一样。

于 2017-03-07T13:45:12.023 回答