2013-12-16 1 views
3

Мой сервер развертывания запускает сценарий развертывания для каждой новой сборки базы данных.Могу ли я печатать сразу для каждой итерации в цикле?

Часть блоков сценариев ждет завершения еще одной асинхронной операции.

код Блокирующий выглядит следующим образом:

DECLARE @i INT = 0; 
DECLARE @laststatus NVARCHAR(MAX) = N''; 

WHILE @i < 5 
BEGIN 
    -- the real delay is longer 
    WAITFOR DELAY '00:00:01'; 

    -- poll async operation status here 
    SET @i = @i + 1; 

    SET @laststatus = N'status is ' + CAST(@i AS NVARCHAR(MAX)); 
    RAISERROR(@laststatus, 0, 1) WITH NOWAIT; 
END; 

Он использует положение о RAISERROR вместо PRINTWITH NOWAIT потому, что он должен напечатать статус обновления для каждой итерации.

Сервер развертывания запускает скрипт в SQLCMD с этой командой:

sqlcmd.exe -i print_test.sql 

Выход появляется сразу, как это:

статус 1
статус 2
статус 3
состояние 4
состояние 5

Он должен напечатать это после одной секунды:

статус 1

После очередного второго он должен напечатать этот

статус 2

И скоро.

Есть ли способ сделать это в sqlcmd?

+1

Работает отлично для меня. Вы используете это в SSMS? Если вы нажмете на вкладку сообщений, как только начнется запрос? Фокус только устанавливается автоматически, когда запрос прекращает выполнение. –

+2

BTW Вы также можете использовать 'RAISERROR (N'status is% i ', 0, 1, @i) WITH NOWAIT;' без промежуточной переменной. –

+2

@MartinSmith Вы правы в SSMS. Мне нужно то же самое, что и в sqlcmd. Просто заметили, что они ведут себя по-другому для меня! Отредактировал вопрос, чтобы уточнить. –

ответ

1

Вы можете использовать osql вместо этого. Он устарел, но он работает так, как вы ожидаете.

Эквивалентная команда:

osql -E -n -i print_test.sql 

OSQL по умолчанию ожидает имя пользователя и пароль. Используйте ключ -E для использования проверки подлинности Windows. Это противоположно поведению sqlcmd по умолчанию.

osql по умолчанию печатает число для каждой строки в сценарии входного файла.

1> 2> 3> 4> 5> 6> 7> 8> 9> 10> 11> 12> 13> 14> 15>

Используйте переключатель -n для подавления номера строк.

sqlcmd не имеет переключателя -n. Он просто не печатает номера строк, когда установлен переключатель -i.

Мартин Смит привел меня к обходному пути, указав Microsoft Connect item по этому вопросу.

Если вы используете скрипт, который использует RAISERROR WITH NOWAIT, выход тем не менее буферизуется. Это корректно работает с OSQL и SQLCMD от SQL 2008

+0

Или другим обходным решением будет использование SSMS в режиме' sqlcmd' в зависимости от на мотивацию к желанию использовать 'sqlcmd' в первую очередь. –

+1

@MartinSmith Сценарий предназначен для запуска на моем сервере развертывания, вызванного новыми сборками баз данных. Инструменты командной строки - все, что я могу здесь использовать. Вопрос: –

+0

Я отмечаю это как принятое, потому что это сработало для меня. В будущем я буду использовать PowerShell. –

3

Есть ли способ сделать это в sqlcmd?

Не так далеко, насколько я знаю.

Об этом сообщается в Connect. См. RAISERROR WITH NOWAIT not honoured in SQLCMD11

SQLCMD был переписан в SQL 2012 для использования ODBC. Вот небольшая ошибка регрессии , которая, похоже, прокралась. Если у вас есть сценарий , который использует RAISERROR WITH NOWAIT, выход тем не менее буферизуется. Это правильно работает с OSQL и SQLCMD с SQL 2008.

, но в настоящее время не фиксирован.

Возможно, вы можете добавить SELECT размер вашего сетевого пакета (или увеличить существующий размер сообщения), чтобы сбросить буфер в качестве обходного пути.

Например

DECLARE @i INT = 0; 

WHILE @i < 5 
    BEGIN 
     -- poll async operation status here 
     SET @i = @i + 1; 

     PRINT 'status is ' + CAST(@i AS VARCHAR(10)) + SPACE(4000); 

     WAITFOR DELAY '00:00:01'; 
    END; 
+0

Я не тестировал «обходной путь», фактически работает в 'sqlcmd'. Я полагаю, вы могли бы экспериментировать с отправкой все большего количества данных, но его можно просто закодировать, чтобы не отображать вывод до завершения выполнения. –

+0

Заполнение вывода размером больше, чем размер сетевого пакета, не сработало для меня. Замена ПЕЧАТИ с помощью SELECT тоже не работала. Похоже, sqlcmd буферизирует все пакеты до конца партии. osql работает, хотя! См. [Мой ответ] (http://stackoverflow.com/a/20610954/111424). –

+0

"Отправлено Microsoft 24/04/2013 в 10:48 Спасибо за отзыв!Мы учтем это в нашем будущем планировании », и они задаются вопросом, почему я их ненавижу. –

0

У меня был этот вопрос также и предварительно (используя пример), казалось бы, что PowerShell командлет Invoke-SQLCMD не имеет такой же вопрос.

Итак, если вы можете переключить сервер развертывания на вызов сценария powershell, это может быть вариант.

Однако существуют некоторые ограничения invoke-sqlcmd по сравнению с sqlcmd, поэтому проверьте документы. http://msdn.microsoft.com/en-us/library/cc281720.aspx. Ваш пробег может отличаться.

Использование powershell также может упростить метод поставки sqlcmdvariable, который немного хлопотно. Хотя обычно я сейчас решил, что поэтому я снова сломаю все это.

+0

Можете ли вы привести пример в PowerShell? Моя версия Invoke -Sqlcmd, похоже, полностью игнорирует утверждения PRINT. 'Invoke-Sqlcmd -Query" PRINT 'Привет, мир!' "' Не выводит результат. –