Tengo un procedimiento almacenado de muy larga duración en SQL Server 2005 que estoy tratando de depurar, y estoy usando el comando 'imprimir' para hacerlo. El problema es que solo recibo los mensajes de SQL Server al final de mi sproc; me gustaría poder vaciar el búfer de mensajes y ver estos mensajes inmediatamente durante el tiempo de ejecución de la sproc, en lugar de hacerlo final.
sql-server
tsql
printing
Erik Forbes
fuente
fuente
Respuestas:
Usa la
RAISERROR
función:No debe reemplazar completamente todas sus impresiones con raiserror. Si tiene un bucle o un cursor grande en alguna parte, hágalo una o dos veces por iteración o incluso cada varias iteraciones.
Además: aprendí por primera vez acerca de RAISERROR en este enlace, que ahora considero la fuente definitiva sobre el manejo de errores de SQL Server y definitivamente vale la pena leerlo:
http://www.sommarskog.se/error-handling-I.html
fuente
Sobre la base de la respuesta de @JoelCoehoorn, mi enfoque es dejar todas mis declaraciones PRINT en su lugar y simplemente seguirlas con la declaración RAISERROR para causar el vaciado.
Por ejemplo:
La ventaja de este enfoque es que las instrucciones PRINT pueden concatenar cadenas, mientras que RAISERROR no. (De cualquier manera, tiene el mismo número de líneas de código, ya que tendría que declarar y establecer una variable para usar en RAISERROR).
Si, como yo, utiliza AutoHotKey o SSMSBoost o una herramienta equivalente, puede configurar fácilmente un acceso directo como "] flush" para ingresar la línea RAISERROR por usted. Esto le ahorra tiempo si es la misma línea de código cada vez, es decir, no necesita ser personalizado para contener texto específico o una variable.
fuente
RAISERROR()
admite laprintf()
interpolación de cadenas de estilo. Por ejemplo, si@MyVariableName
es un tipo stringish (por ejemplo,VARCHAR(MAX)
,NVARCHAR(MAX)
, etc.), se puede utilizarRAISERROR()
con una línea:RAISERROR(N'MyVariableName: %s', 0, 1, @MyVariableName)
.Sí ... El primer parámetro de la función RAISERROR necesita una variable NVARCHAR. Entonces intente lo siguiente;
O
fuente
Otra mejor opción es no depender de PRINT o RAISERROR y simplemente cargar sus declaraciones "print" en una tabla ## Temp en TempDB o una tabla permanente en su base de datos que le dará visibilidad de los datos inmediatamente a través de una declaración SELECT desde otra ventana . Esto funciona mejor para mí. El uso de una tabla permanente también sirve como un registro de lo que sucedió en el pasado. Las declaraciones de impresión son útiles para errores, pero utilizando la tabla de registro también puede determinar el punto exacto de falla en función del último valor registrado para esa ejecución en particular (suponiendo que rastrea el tiempo de inicio de ejecución general en su tabla de registro).
fuente
SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
en su sesión de monitoreoREAD UNCOMMITTED
transacción a otra tabla, pero probablemente se pierda el momento justo antesROLLBACK
. Entonces, probablemente resuelva el '¿hasta dónde?' no el '¿por qué retroceder?'Solo como referencia, si trabaja en scripts (procesamiento por lotes), no en un procedimiento almacenado , el comando GO activa la salida de vaciado, por ejemplo
En general, mi conclusión es la siguiente: la salida de la ejecución del script mssql, que se ejecuta en la GUI de SMS o con sqlcmd.exe, se vacía en el archivo, stdoutput, ventana gui en la primera instrucción GO o hasta el final del script.
El vaciado dentro del procedimiento almacenado funciona de manera diferente, ya que no puede colocar GO dentro.
Referencia: instrucción tsql Go
fuente
go
no solo descarga la salida, finaliza el lote según el enlace que proporcionó. Todo lo quedeclare
deseches se descarta, por lo que no es muy útil para la depuración.declare @test int print "I want to read this!" go set @test=5
aunque un error de reclamo@test
no está definido porque está en un nuevo lote.