【问题标题】:Workaround to RAISERROR WITH NOWAIT bufferingRAISERROR WITH NOWAIT 缓冲的解决方法
【发布时间】:2014-11-02 23:49:55
【问题描述】:

我使用 RAISERROR 从存储过程而不是使用 PRINT 生成进度输出,以避免 PRINT 对输出进行缓冲。现在我发现 RAISERROR 将在 500 次打印后开始缓冲。有没有办法解决这种行为? 下面的查询将表明我的观点:

DECLARE @i INT = 0

WHILE @i < 50000
BEGIN
    SET @i = @i + 1 

    RAISERROR('%i prints', 0,1 , @i) with nowait;

    IF @i > 500  --<--after 500 prints RAISERROR starts buffering 50 prints before flushing.
    WAITFOR DELAY '00:00:00.050';
END; 

【问题讨论】:

  • 您是否考虑过通过写入日志表而不是依赖客户端字符串输出来检测存储过程?如果您需要自主事务支持,您可以使用环回链接服务器的技巧 (dbbest.com/blog/autonomous-transactions-sql-server)
  • 我使用脚本来备份和恢复数百个数据库,并且想要进度输出 printet 而不是记录在表中,因为 BACKUP 和 RESTORE 的进度输出是 printet
  • @NWest 你可以使用@table 变量,它不受事务回滚的影响,不需要各种令人发指的变通办法。

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


【解决方案1】:

Erland Sommerskand reported:

但是,请注意 Mgmt Studio 也会开始缓冲 NOWAIT 消息 500 条消息后。

SQL 附带的旧查询分析器不会发生这种情况 2000

如果您没有可用的 QA,也许您可​​以尝试 SQLCMD.EXE 而不是 SSMS。可能 500 之后就不做缓冲了。

【讨论】:

  • 这与 SQLCMD.EXE 的行为相同,我想我不能在 SQL Server 2008 中使用 QA ?!
  • @jhe 当然,您可以将查询分析器与 SQL Server 2008 一起使用,只是除了充当哑查询窗口之外不要尝试做太多事情。 Enterprise Mangler 将是一个不同的故事。
【解决方案2】:

我记得在 LINQpad 中尝试过,linqpad 可以接受原始 sql,并且没有缓冲区。

我又试了一次,我可以确认。

你可以使用 linqpad 吗?

【讨论】:

  • 可能是一个解决方案,但由于这在生产中经常发生,我们并不总是被允许安装软件。
  • @jhe,你不必安装 linqpad,你可以从 linqpad 网站(独立)下载一个 zip 文件,然后简单地解压然后运行它,这一切都无需安装
  • 此外,您可以将 LINQpad 客户端放在任何具有 SQL 连接的开发人员机器上;它不必在生产服务器上。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-12
  • 2021-06-05
相关资源
最近更新 更多