【问题标题】:Why do people use RaiseError instead of Print in T-SQL为什么人们在 T-SQL 中使用 RaiseError 而不是 Print
【发布时间】:2012-07-24 21:07:12
【问题描述】:

我已经尝试了以下两个查询,它们同时执行。但我仍然看到在许多存储过程中使用 RaiseError 而不是打印。

查询 1:

BEGIN
    WAITFOR DELAY '00:00:03.00'

    PRINT 'DELAY 1 HAS ENDED'

    WAITFOR DELAY '00:00:03.00'

    PRINT 'DELAY 2 HAS ENDED'
END

查询 2:

BEGIN
    WAITFOR DELAY '00:00:03.00'

    RAISERROR ('DELAY 1 HAS ENDED', 10,1) WITH NOWAIT

    WAITFOR DELAY '00:00:03.00'

    RAISERROR ('DELAY 2 HAS ENDED', 10,1) WITH NOWAIT

END

两者都只在 6 秒后给出所需的输出(我在 SQL Server 2008 R2 中检查过)

【问题讨论】:

    标签: sql tsql sql-server-2008-r2


    【解决方案1】:

    RAISERROR 相对于PRINT 的优势在于您可以在消息中嵌入变量值,而不必为CASTCONVERT 操心。 例如:

     BEGIN
         DECLARE @m INT = 0
    
         WAITFOR DELAY '00:00:01.00'
         SET @m += 1;
         RAISERROR ('DELAY %d HAS ENDED', 10, 1, @m)
     
         WAITFOR DELAY '00:00:01.00'     
         SET @m += 1;
         RAISERROR ('DELAY %d HAS ENDED', 10, 1, @m)
     
     END
    

    这将在上面的两个示例中产生相同的输出,除了它将变量的值插入到消息中。使用PRINT,您必须这样做:

    PRINT 'DELAY ' + CONVERT(VARCHAR(5), @m) + ' HAS ENDED'
    

    ...可行但很麻烦...

    【讨论】:

    • RAISERROR 的另一个优点是您可以添加WITH NOWAIT 选项:然后您可以立即在 sqlserver 管理工作室的消息选项卡中获取消息,并且您不必等待消息缓冲区填充:这在长时间运行的查询中很有用。确实,在大约 30 秒以下的短查询中可能看不到 WITH NOWAIT 的效果。同样真实的是,一段时间后WITH NOWAIT 的效果结束并且输出再次被缓冲(约50 Kb 的消息)。不过,这不会影响 SQLCMD 的行为...
    【解决方案2】:

    我的服务器版本和你一样,查询 2 在 3 秒后打印第一个结果(如预期的那样)。您必须在 Microsoft SQL Server Management Studio 中自行切换到“消息”选项卡才能看到消息。

    【讨论】:

    • +1 消息选项卡不会自动切换到查询在 6 秒后结束,但 RAISERROR 仍然会在 3 秒后打印第一条消息。在 2008 R2 上测试。
    【解决方案3】:

    我们使用 RAISERROR 来更轻松地跟踪实际错误。这很方便,因为您可以设置项目的严重性,并且您可以立即在“消息”部分看到结果。

    PRINT 用于多步骤过程中的真正便宜/快速的调试器,它显示了当我实际上并不期望立即得到反馈时我们实际取得了多远。

    【讨论】:

      【解决方案4】:

      有一个返回语句缓冲区导致 PRINT 语句仅在满时刷新(或 SQL Server 设计这样做)。 RAISERROR(x, y, z) WITH NOWAIT 要么不使用该缓冲区,要么在添加其消息后似乎强制刷新该缓冲区。

      除了这个和 Philippe 在他的回答中提到的嵌入式变量行为之外,低严重性 RAISERROR 和 PRINT 之间似乎没有真正的功能差异。

      这是 Louis Davidson (@drsql) 的 2018 年简短帖子,其中包含更多代码示例和其他帖子的链接,其中包含更多详细信息:https://www.red-gate.com/simple-talk/blogs/outputting-status-t-sql-code/

      对于我来说,在等待 PRINT 语句通过后感到沮丧后,我现在使用“RAISERROR(@msg, 0, 42) WITH NOWAIT”作为批处理脚本进度输出。

      【讨论】:

        猜你喜欢
        • 2022-12-11
        • 1970-01-01
        • 2021-10-12
        • 2020-02-10
        • 2019-04-01
        • 2014-10-28
        • 2017-08-17
        • 2014-07-13
        • 2019-04-14
        相关资源
        最近更新 更多