在我得到我重申的答案之前;我承认我在这里接受的唯一答案是KM的这个答案。以上。我对其他答案投了反对票,因为他们都没有真正回答所提出的问题,或者他们不够充分。PRINT 输出确实显示在消息窗口中,但这根本不是所要求的。
为什么在我的存储过程执行期间不显示 PRINT 语句输出?
这个答案的简短版本是您将存储过程的执行发送到 SQL 服务器,并且在完成整个事务之前它不会响应。这是位于此外部链接的更好答案。
- 如需更多意见/观察,请将您的注意力集中在此 SO 帖子上。
- 具体看Phil_factor同一篇文章的这个答案(哈哈!喜欢SQL幽默)
- 关于使用 RAISERROR WITH NOWAIT 的建议,请查看JimCarden对同一篇文章的回答
不要做这些事
- 有些人的印象是他们可以在 PRINT 语句之后使用 GO 语句,但不能在 sproc 的内部使用 GO 语句。所以这个解决方案就出来了。
- 我不建议选择你的打印语句,因为它只会用废话混淆你的结果集,如果你的 sproc 应该被程序稍后使用,那么你必须知道循环时要跳过哪些结果集通过数据阅读器的结果。这只是一个坏主意,所以不要这样做。
- 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。