У меня есть очень долго выполняемая хранимая процедура в SQL Server 2005, которую я пытаюсь отладить, и для этого я использую команду «печать». Проблема в том, что я получаю сообщения только от SQL Server в самом конце моего sproc - я хотел бы иметь возможность очистить буфер сообщений и видеть эти сообщения сразу во время выполнения sproc, а не в самом конец.
sql-server
tsql
printing
Эрик Форбс
источник
источник
Ответы:
Используйте
RAISERROR
функцию:Вы не должны полностью заменять все свои отпечатки на raiserror. Если у вас есть петля или большой курсор где-то, просто сделайте это один или два раза за итерацию или даже каждые несколько итераций.
Кроме того: я впервые узнал о RAISERROR по этой ссылке, которую я сейчас рассматриваю как окончательный источник информации об обработке ошибок SQL Server и которую стоит прочитать:
http://www.sommarskog.se/error-handling-I.html
источник
Основываясь на ответе @JoelCoehoorn, мой подход состоит в том, чтобы оставить все мои операторы PRINT на месте и просто следовать им с помощью оператора RAISERROR, чтобы вызвать сброс.
Например:
Преимущество этого подхода состоит в том, что операторы PRINT могут объединять строки, а RAISERROR - нет. (Таким образом, в любом случае у вас будет такое же количество строк кода, как и в случае объявления и установки переменной для использования в RAISERROR).
Если, как и я, вы используете AutoHotKey или SSMSBoost или эквивалентный инструмент, вы можете легко настроить ярлык, например "] flush", чтобы ввести для вас строку RAISERROR. Это экономит ваше время, если каждый раз используется одна и та же строка кода, т. Е. Не требует настройки для хранения определенного текста или переменной.
источник
RAISERROR()
поддерживаетсяprintf()
интерполяция строк в стиле. Например, если@MyVariableName
тип stringish (например,VARCHAR(MAX)
,NVARCHAR(MAX)
и т.д.), вы можете использоватьRAISERROR()
с одной строкой:RAISERROR(N'MyVariableName: %s', 0, 1, @MyVariableName)
.Да ... Первый параметр функции RAISERROR нуждается в переменной NVARCHAR. Так что попробуйте следующее;
ИЛИ
источник
Другой лучший вариант - не зависеть от PRINT или RAISERROR, а просто загружать ваши операторы «print» в таблицу ## Temp в TempDB или постоянную таблицу в вашей базе данных, которая немедленно предоставит вам видимость данных через оператор SELECT из другого окна. , Это работает лучше всего для меня. Использование постоянной таблицы также служит в качестве журнала того, что произошло в прошлом. Операторы печати удобны для ошибок, но с помощью таблицы журнала вы также можете определить точную точку отказа на основе последнего зарегистрированного значения для этого конкретного выполнения (при условии, что вы отслеживаете общее время начала выполнения в своей таблице журнала).
источник
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
в своем сеансе мониторингаREAD UNCOMMITTED
транзакции в другую таблицу, но вы, вероятно, упускаете момент прямо перед этимROLLBACK
. Так что это, вероятно, решает, "как далеко?" не "почему откат?"Просто для справки: если вы работаете в сценариях (пакетная обработка), а не в хранимой процедуре , сброс данных запускается командой GO, например
В общем, мой вывод следующий: вывод выполнения скрипта mssql, выполняющегося в графическом интерфейсе SMS или с помощью sqlcmd.exe, сбрасывается в файл, stdoutput, окно графического интерфейса при первом операторе GO или до конца скрипта.
Промывка внутри хранимой процедуры работает иначе, так как вы не можете поместить GO внутрь.
Ссылка: заявление tsql Go
источник
go
не просто сбрасывает вывод, он завершает пакет согласно предоставленной вами ссылке. Все, что вы делаете,declare
отбрасывается, поэтому не очень пригодно для отладки.declare @test int print "I want to read this!" go set @test=5
Будет ли, однако, ошибка, требующая@test
подтверждения, не определена, поскольку она находится в новой партии.