Рекомендации - ведение журнала хранимых процедур
Если у вас длинный SP, вы каким-то образом регистрируете его действия или просто ждете этого сообщения?
"Команда успешно завершена."
Я предполагаю, что на эту тему может быть много решений, но есть ли какая-нибудь лучшая практика - простое решение, которое часто используется?
ИЗМЕНИТЬ
Я нашел интересную ссылку на эту тему
http://weblogs.sqlteam.com/brettk/archive/2006/09/21/12391.aspx
В статье описывается использование таблицы журналов, но есть проблема
Процедура ведения журнала должна выполняться вне любой транзакции
Я не могу вызывать эту вставку вне, из-за того, что я использую курсор и вставляю строку в эту таблицу в каждой строке.
Любые идеи?
РЕДАКТИРОВАТЬ 2
Рытье..
есть xp_logevent в SQL Server. Вы попробовали?
Как насчет Профайлер SQL Server?
Здесь также Создание файла журнала для хранимой процедуры
Ответы
Ответ 1
Как вы вызываете хранимую процедуру? Если это происходит через Management Studio, вы можете легко распечатать сообщение следующим образом
RAISERROR ('Some debugging info', 0, 1) WITH NOWAIT
Это предпочтительнее использовать PRINT
, поскольку сообщение появится немедленно. Эти сообщения также могут быть обнаружены в ADO.NET, проводя проводник для события Connection.InfoMessage.
Я вижу, что вы уже указали SQL Profiler как возможность. Вам может быть интересно узнать, что вы можете регистрировать собственные настраиваемые пользователем события, которые можно увидеть в SQL Profiler.
Ответ 2
Чтобы увидеть, сколько времени требуется, и сколько строк изменило предыдущее действие, я добавляю текущую дату + время и количество последних строк в каждую запись. Я использую эту процедуру:
CREATE PROCEDURE dbo.[Log]
@Message NVARCHAR(512),
@RowCount INT = null OUTPUT,
@Delimiter NCHAR(1) = N' ',
@PadChar NCHAR(1) = N'-'
AS
BEGIN
SET @RowCount = @@ROWCOUNT;
DECLARE @LogDate AS NVARCHAR(50);
DECLARE @RowCountPadded AS NCHAR(8);
SET @LogDate = CONVERT(NVARCHAR(50),GETDATE(),121);
SELECT @RowCountPadded = CASE @RowCount WHEN 0 THEN REPLICATE(@PadChar,8) ELSE REPLACE(STR(@RowCount, 8), SPACE(1), @PadChar) END;
SET @Message = @LogDate + @Delimiter + @RowCountPadded + @Delimiter + @Message;
RAISERROR (@Message, 0, 1) WITH NOWAIT;
END
Итак, в ваших процедурах добавьте вывод журнала следующим образом:
EXEC dbo.[Log] 'the message';
Он производит это:
2012-12-28 11:28:25.197 -------- the message
Если бы вы выполнили какое-либо действие ранее, вы увидите число строк, в котором находятся тире. Если вам нужен счетчик строк для чего-то другого (например, для входа в таблицу), вы можете вернуть его из процедуры в качестве параметра OUTPUT.
UPDATE. Используйте эту gist, если вы хотите создать эту процедуру один раз и использовать ее повсюду.
Ответ 3
Обычно мы используем таблицы протоколирования и заботимся о транзакциях. Мы почти избегаем всего, что связано с выходом за пределы SQL Server (например, запись в файловую систему, вызов внешних служб, сборки .NET и т.д.).
Мы также стараемся избегать курсоров - возможно ли, что ваш proc длинный, потому что он неэффективен?
Ответ 4
Я использую эту процедуру
CREATE PROCEDURE dbo.PrintLog (
@Msg VARCHAR(2048)
, @Option VARCHAR(100) = ''
, @Separator VARCHAR(10) = '-'
)
/*
@Option is a string containing possible values as B,A,D,T
if you want to print separator before message, include B
if you want to print separator after message, include A
if you want to print date, include D
if you want to print time, include T
Sample: 'BAD'
The order of characters does not matter. it is not case sensitive
Usage:
exec dbo.PrintLog 'Timed Log', 'T'
exec dbo.PrintLog 'Dated Log', 'D'
exec dbo.PrintLog 'With Separator and Time', 'BT', '><'
exec dbo.PrintLog 'With Separator and Date', 'BAD', '*'
exec dbo.PrintLog 'With Separator and DateTime', 'BADT', 'x'
*/
AS
BEGIN
declare @tempStr varchar(100)
set @tempStr = replicate(@Separator, 50)
IF charindex('B', upper(@Option)) > 0
raiserror (@tempStr, 10, 1) with nowait
DECLARE @prompt VARCHAR(max) = ''
IF charindex('D', upper(@Option)) > 0
SET @prompt = convert(VARCHAR, SysDatetime(), 101) + ' '
IF charindex('T', upper(@Option)) > 0
SET @prompt = @prompt + convert(VARCHAR, SysDatetime(), 108) + ' '
SET @prompt = @prompt + @Msg
raiserror (@prompt, 10, 1) with nowait
set @tempStr = replicate(@Separator, 50)
IF charindex('A', upper(@Option)) > 0
raiserror (@tempStr, 10, 1) with nowait
RETURN
END
GO
Использование
exec dbo.PrintLog 'Date and Timed Log', 'DT'
exec dbo.PrintLog 'Dated Log', 'D'
exec dbo.PrintLog 'With Separator and Time', 'BT', '><'
exec dbo.PrintLog 'With Separator and Date', 'BAD', '*'
exec dbo.PrintLog 'With Separator and DateTime', 'BADT', 'x'
Вы также можете изменить параметры по умолчанию на нужные вам значения.