2010-05-30 17 views
20

Si tiene un SP de larga ejecución, ¿registra de alguna manera sus acciones o simplemente espera a recibir este mensaje?Mejores prácticas: registro de procedimientos almacenados

"Comandos completados correctamente".

Supongo que puede haber muchas soluciones sobre este tema, pero ¿hay alguna mejor práctica, una solución simple que se utiliza con frecuencia?

EDITAR

he encontrado un enlace interesante sobre este tema

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

artículo describe el uso de una tabla de registro, pero hay un problema

El procedimiento de registro debe ejecutarse fuera de cualquier transacción

No puedo llamar a esa inserción afuera, debido al cursor que uso e inserte una línea a esa tabla en cada fila.

¿Alguna idea?

EDITAR

de excavación ..

hay un xp_logevent de SQL Server. ¿Lo intentaste?

¿Qué hay de SQL Server Profiler?

También hay Creating Log file for Stored Procedure

+0

define long running? –

+0

Cualquier sp, eso es más que un par de selecciones y actualizaciones. Por ejemplo, si usa el cursor y necesita ver el progreso. ¿Hay algo malo con mi pregunta? – hgulyan

Respuesta

22

¿Cómo invoca el procedimiento almacenado? Si es a través de estudio de la gerencia a continuación, puede imprimir fácilmente el mensaje de la siguiente manera

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

Esto es preferible al uso de PRINT como el mensaje aparecerá inmediatamente. Estos mensajes también pueden capturarse en ADO.NET conectando un controlador para el evento Connection.InfoMessage.

Veo que ya ha enumerado SQL Profiler como una posibilidad. Puede que le interese saber que puede log your own user configurable events que se puede ver en SQL Profiler.

+1

Invoco sp en Management Studio, pero la pregunta es general, por lo que si hay una buena forma de iniciar sesión, también se puede usar en la aplicación. No necesito RAISERROR, porque necesito registrar el proceso, no errores. PRINT puede ser una opción, pero ¿qué pasa si sp imprime como 1000 filas por segundo? Ya he probado SQL Profiler. Es una buena opción, pero en realidad no es un registro. Es más monitoreo, supongo, y Profiler no es una solución general. Quizás la solución esté combinando todo lo que se dijo aquí. – hgulyan

+1

No se deje confundir por el nombre RAISERROR no es solo por errores. Cualquier cosa con una gravedad inferior a 10 es solo para mensajes de información. Claramente, cualquiera que sea el marco de trabajo de registro que use, debe diseñarlo de forma que se registre una cantidad adecuada de información. –

+0

¿Raiserror no detendrá la sp? p.s. y gracias por la configuración de usuario personalizada en Profiler. gracias enlace más interesante sobre este tema. – hgulyan

3

regla general, utilizamos las tablas de registro y cuidar alrededor transacciones. Evitamos todo lo que implique salir de SQL Server (por ejemplo, escribir en el sistema de archivos, llamar a servicios externos, ensamblados .NET, etc.)

También tratamos de evitar los cursores: ¿es posible que su proceso sea de larga ejecución porque es ineficiente?

+0

¿Puedes ser más específico? ¿Qué sucede si no puede insertar en su tabla de registro fuera de una transacción? sé, que no se recomiendan los cursores, pero es un tiempo de escritura usada y no hay otro camino, por lo que este es un caso cuando los cursores son necesarios. – hgulyan

7

Para ver cuánto tardan las cosas y cuántas filas modificó la acción anterior, agrego la fecha actual + hora y la última fila para cada entrada.Yo uso este procedimiento:

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 

Así, en sus procedimientos, añadir la salida del registro de esta manera:

EXEC dbo.[Log] 'the message'; 

Se produce esto:

2012-12-28 11:28:25.197 -------- the message 

Tenía que ha realizado alguna acción con anterioridad, Vería el recuento de filas donde están los guiones. Si necesita el recuento de filas para otra cosa (por ejemplo, para iniciar sesión en una tabla), puede recuperarlo del procedimiento como un parámetro OUTPUT.

ACTUALIZACIÓN: Utilice esta gist si desea crear este procedimiento una vez y usarlo en todas partes.

0

que utiliza este procedimiento

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 

Uso

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' 

También puede cambiar los valores predeterminados de los parámetros a que desean valores.

Cuestiones relacionadas