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. Это также работает, но результаты таблицы, как правило, перемешиваются и трудно читаются на экране командной консоли...