最佳实践 - 存储过程日志记录

时间:2010-05-30 09:34:16

标签: sql-server logging

如果您有一个长时间运行的SP,您是否以某种方式记录其操作或只是等待此消息?

  

“命令已成功完成。”

我认为,关于这个问题可以有很多解决方案,但有没有最佳实践 - 经常使用的简单解决方案?

修改

我在这个主题上找到了一个有趣的链接

http://weblogs.sqlteam.com/brettk/archive/2006/09/21/12391.aspx

文章描述了使用日志表,但存在问题

  

日志记录程序必须在任何交易之外执行

我无法在外面调用该插入,因为我使用了游标并在每一行上向该表插入一行。

有什么想法吗?

编辑2

挖..

SQL Server中有xp_logevent。你试过吗?

SQL Server Profiler 怎么样?

还有Creating Log file for Stored Procedure

4 个答案:

答案 0 :(得分:22)

您是如何调用存储过程的?如果是通过Management Studio,那么您可以轻松打印出如下消息

RAISERROR ('Some debugging info', 0, 1) WITH NOWAIT

这比使用PRINT更好,因为消息会立即显示。通过连接Connection.InfoMessage事件的处理程序,也可以在ADO.NET中捕获这些消息。

我看到您已经列出了SQL Profiler的可能性。您可能有兴趣知道可以在SQL事件探查器中看到log your own user configurable events

答案 1 :(得分:9)

为了查看事情花了多长时间,以及之前操作修改了多少行,我将当前日期+时间和最后一行计数添加到每个条目。我用这个程序:

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参数返回。

更新:如果您想创建此过程一次并在任何地方使用它,请使用此gist

- 删除行---

答案 2 :(得分:3)

我们通常使用日志记录表并处理事务。我们几乎避免涉及到SQL Server之外的任何事情(例如写入文件系统,调用外部服务,.NET程序集等)。

我们也试图避免使用游标 - 你的proc是否可能长时间运行,因为它效率低下?

答案 3 :(得分:2)

我使用这个程序

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'

您也可以将参数默认值更改为所需的值。