2008-11-06 14 views
59

¿Por qué la instrucción PRINT en T-SQL parece funcionar solo algunas veces? ¿Cuáles son las limitaciones para usarlo? A veces parece que si se genera un conjunto de resultados, se convierte en una función nula, supongo que para evitar la corrupción del conjunto de resultados, pero ¿no podría salir en otro conjunto de resultados, como el recuento de filas?instrucción PRINT en T-SQL

+2

Podría dar un ejemplo de un código que a veces se imprime, y otras veces no. No creo entender la pregunta –

Respuesta

85

Entonces, si tiene una declaración como la siguiente, ¿está diciendo que no obtiene el resultado de 'impresión'?

select * from sysobjects 
PRINT 'Just selected * from sysobjects'

Si está utilizando el Analizador de consultas SQL, verá que hay dos pestañas hacia abajo en la parte inferior, una de las cuales es "Mensajes" y ahí es donde las declaraciones de 'imprimir' se mostrará.
Si usted está preocupado por el tiempo de ver las declaraciones de impresión, es posible que desee intentar usar algo así como

raiserror ('My Print Statement', 10,1) with nowait

Esto le dará el mensaje de inmediato como se alcanza el estado, en lugar de amortiguar el salida, como lo hará el Analizador de consultas bajo la mayoría de las condiciones.

+1

Buen trato. Me alegro de que esto haya funcionado para ti. Por lo general, le digo al analizador de consultas que me dé salida de texto para que pueda ver los mensajes en línea (Ctrl + T). ¡Disfrutar! –

+1

¿Cuáles son los argumentos 10 y 1 en el ejemplo raiserror? –

+0

Los 10, 1 realmente solo dicen "nada que ver aquí" en el servidor. Consulte https://docs.microsoft.com/en-us/sql/t-sql/language-elements/raiserror-transact-sql#arguments para obtener detalles sobre lo que realmente significan. –

34

La declaración de impresión en TSQL es una criatura incomprendida, probablemente debido a su nombre. De hecho, envía un mensaje al mecanismo de gestión de errores/mensajes que luego lo transfiere a la aplicación de llamada. PRINT es bastante tonto. Solo puede enviar 8000 caracteres (4000 caracteres unicode). Puede enviar una cadena literal, una variable de cadena (varchar o char) o una expresión de cadena. Si usa RAISERROR, está limitado a una cadena de 2.044 caracteres. Sin embargo, es mucho más fácil usarlo para enviar información a la aplicación llamante, ya que llama a una función de formateo similar a la anterior printf en la biblioteca C estándar. RAISERROR también puede especificar un número de error, una gravedad y un código de estado además del mensaje de texto, y también se puede usar para devolver mensajes definidos por el usuario creados mediante el procedimiento almacenado del sistema sp_addmessage. También puede forzar que los mensajes se registren.

Sus rutinas de manejo de errores no serán de ninguna utilidad para recibir mensajes, a pesar de que los mensajes y errores son muy similares. La técnica varía, por supuesto, según la forma real de conectarse a la base de datos (OLBC, OLEDB, etc.). Para recibir y tratar los mensajes del Motor de base de datos de SQL Server, cuando use System.Data.SQLClient, deberá crear un delegado SqlInfoMessageEventHandler, identificando el método que maneja el evento, para escuchar el evento InfoMessage. en la clase SqlConnection. Encontrará que la información del contexto del mensaje, como la gravedad y el estado, se pasa como argumentos a la devolución de llamada, porque desde la perspectiva del sistema, estos mensajes son como errores.

Siempre es una buena idea tener una forma de obtener estos mensajes en su aplicación, incluso si solo está cargando en un archivo, porque siempre habrá un uso para ellos cuando intente perseguir un mensaje. problema realmente oscuro. Sin embargo, no creo que quiera que los usuarios finales los vean a menos que pueda reservar un nivel informativo que muestre cosas en la aplicación.

2

Para el beneficio de cualquier otra persona que lea esta pregunta que realmente le faltan las instrucciones de impresión de su salida, en realidad hay casos en que la impresión se ejecuta pero no se devuelve al cliente. No puedo decirte específicamente qué son. Puedo decirle que si coloca una declaración de ir inmediatamente antes y después de cualquier declaración de impresión, la verá si se ejecuta.

+0

También he experimentado casos en los que una declaración de impresión escribe en la ventana de mensajes cuando se espera. Me sucede después de un commit o un rollback. –

21

El analizador de consultas almacena temporalmente los mensajes. Las instrucciones PRINT y RAISERROR utilizan este búfer, pero la instrucción RAISERROR tiene una opción WITH NOWAIT.Para imprimir un mensaje de usarlo inmediatamente lo siguiente:

RAISERROR ('Your message', 0, 1) WITH NOWAIT 

RAISERROR sólo mostrará 400 caracteres de sus mensajes y utiliza una sintaxis similar a la función printf C para el formato de texto.

Tenga en cuenta que el uso de RAISERROR con la opción WITH NOWAIT vaciará el búfer de mensajes, por lo que también se generará toda la información previamente almacenada en el búfer.

+1

La sintaxis RAISERROR fue un problema, pero poner una vacía después de que mi PRINT hizo el trabajo, ¡gracias por la información! – Cobusve

18

Recientemente me encontré con esto, y terminó siendo porque tenía una declaración de conversión en una variable nula. Como eso causaba errores, la declaración de impresión completa se mostraba nula y no se imprimía en absoluto.

Ejemplo - Este fallará:

declare @myID int=null 
print 'First Statement: ' + convert(varchar(4), @myID) 

Ejemplo - Esto imprimirá:

declare @myID int=null 
print 'Second Statement: ' + coalesce(Convert(varchar(4), @myID),'@myID is null') 
+0

No solo IMPRESIÓN: el uso del operador + con cualquier valor nulo en cualquier parte de T-SQL da como resultado un valor nulo, independientemente de si había otras cosas para concatenar juntas que no fueran nulas. El uso de ISNULL (@miID, '') o COALESCE como lo ha hecho permitirá que el nulo se pueda concatenar con cadenas. – troy

0

¿Tiene las variables que se asocian con estas declaraciones de impresión estado de salida? si es así, he encontrado que si la variable no tiene valor, la declaración de impresión no se publicará.

+0

Parece que no entiende el efecto de concatenar 'NULL' con una cadena. 'PRINT 'a' + CAST (NULL AS VARCHAR (MAX));' se comporta exactamente como yo esperaba. – binki