RAISERROR с NOWAIT не так сразу?

я ранее задавал вопрос о том, как сделать PRINT это дает вывод сразу, пока остальная часть скрипта все еще работает (см.:как увидеть ход выполнения хранимых процедур SQL?). Простой ответ-использовать:

RAISERROR ('My message', 0, 1) WITH NOWAIT

однако я заметил, что возвращаемый вывод не всегда является немедленным, особенно когда он возвращает много результатов. В качестве простого эксперимента, рассмотрим следующий скрипт:

DECLARE @count INT
SET @count = 1

WHILE @count <= 5000
BEGIN
    RAISERROR ('Message %d', 0, 1, @count) WITH NOWAIT
    WAITFOR DELAY '00:00:00.01'
    SET @count = @count + 1
END

вышеприведенный скрипт выплевывает 5000 строк текста. Если вы запустите скрипт, вы заметите:

  • для первых 500 строк (1-500 строк) он немедленно возвращает каждую выходную строку.
  • для следующих 500 строк (501 - 1000 строк) он возвращает вывод один раз каждые 50 строк. (Все 50 строк будут объединены в пакет и возвращены только в конце каждой 50-й строки.)
  • для каждой строки после этого (1001 - * строк) он возвращает вывод один раз каждые 100 строк. (Все 100 строк Складывайте вместе и возвращайте только в конце каждой 100-й строки.)

Это означает, что после первых 500 строк RAISERROR WITH NOWAIT больше не работает, как ожидалось, и вызывает проблемы для меня, потому что я хочу видеть прогресс моего очень долгого сценария.

Итак, мой вопрос: есть ли способ отключить это "пакетированное" поведение и заставить его всегда возвращаться немедленно?


EDIT: я использую SSMS (SQL Server Management Studio) для запустите приведенный выше сценарий . Похоже, это влияет на все версии (как SSMS, так и SQL Server), и независимо от того, установлен ли вывод "результаты в текст" или "результаты в сетку", не имеет значения.

EDIT: по-видимому, это пакетированное поведение происходит после 500 строк,независимо от из числа байтов. Итак, я соответствующим образом обновил вопрос выше.

EDIT: спасибо Fredou для указания на то, что это проблема с SSMS и сторонние инструменты, такие как помощью linqpad не будет этой проблемы.

однако, я узнал, что помощью linqpad не выводится сразу же, когда у вас есть результаты таблицы на выходе. Например, рассмотрим следующий код:

RAISERROR ('You should see this immediately', 0, 1) WITH NOWAIT
SELECT * FROM master.sys.databases
RAISERROR ('You should see this immediately too, along with a table above.', 0, 1) WITH NOWAIT
WAITFOR DELAY '00:00:05'
RAISERROR ('You should see this 5 seconds later...', 0, 1) WITH NOWAIT

при запуске вышеуказанного скрипта в LinqPad выводится только первая строка. Остальное будет выводиться только через 5 секунд...

Итак, кто-нибудь знает хорошую легкую альтернативу для SSMS, которая бесплатна, не требует установки и будет работать с немедленными выходами RAISERROR с NOWAIT, смешанными с результатами таблицы?

3 ответов


кажется, это ограничение SQL server management studio >= 2005

Если у вас есть 2000, у вас не будет этого ограничения

источник

Я только что попробовал ваш код с LinqPad, и я не могу воспроизвести это поведение


Запрос ExPlus кажется, делает трюк, пока вы установите параметр вывода в "результаты в тексте".

еще одна грубая альтернатива sqlcmd, который устанавливается как часть SQL Server. Это также работает, но результаты таблицы, как правило, перемешиваются и трудно читаются на экране командной консоли...


казалось бы, это работает в 2008R2, если вы установите результаты в текст. enter image description here