Antes que nada, permitidme presentar este nuevo blog en el que un programador cualquiera, de una empresa cualquiera, tratará de contaros el día a día de sus peripecias con Microsoft SQL Server. Como dicen que la experiencia es un grado y que de los errores se aprende, intentaré desde estas líneas que l@s mí@s puedan serviros cuando os veáis en las mismas diatribas que me han llevado a escribir estas líneas. Sin más, allá vamos.
Entre las muchas instrucciones de configuración que nos ofrece Microsoft SQL Server, hay una cuyo uso no parece aportar demasiado, pero que es vital si no queréis enfrentaros a "fenómenos paranormales" en algunas de vuestras queries.
Se trata de SET NOCOUNT ON
Activar esta opción (el ON del final es lo que la activa), equivale a decirle al servidor de base de datos que no queremos que nos devuelva le número de filas afectadas por las instrucciones ejecutadas.
Este comportamiento, que podemos observar normalmente cuando ejecutamos cualquier consulta sobre el Management Studio, afecta a SELECT, DELETE, INSERT y UPDATE. Tras ejecutar cualquiera de estas instrucciones, podemos observar como SQL Sever nos indica el número de filas afectadas por la instrucción.
Pero, ¿qué ocurre si ante cualquiera de las tres anteriores que modifican datos (DELETE, INSERT, UPDATE) se ejecuta detrás algún trigger? La respuesta es fácil: SQL nos devuelve por separado el número de filas afectadas por la instrucción principal (la llamante) y la(s) que se encuentra(n) en el trigger.
Para evitar que SQL Server nos devuelva el conjunto de filas afectadas por cualquier instrucción o query escrita en el trigger, sólo debemos añadir nuestro citado SET NOCOUNT ON al principio de la definición del mismo. Lo mismo es válido para procedimientos almacenados.
De esta forma, dejaremos de recibir el resultado de las filas afectadas. Evidentemente, su utilidad va más allá que la mera información que dejamos de ver en el Management Studio. Su utilidad principal reside en evitar que esta información altere con el conjunto de resultados que queremos que SQL Server nos devuelva.
Así, si ejecutamos una query desde cualquier aplicación, tras la que se acaban ejecutando triggers, la no inclusión de SET NOCOUNT ON en la definición del trigger (En ADO/C++ se actualizan los campos de tipo image o ntext mediante SELECT) o procedimiento almacenado hará que los resultados que obtengamos con la SELECT no sean los esperados y, muy probablemente, nos causen un error.
La magia del SET NOCOUNT ON es, pues, que evitamos que consultas "escondidas" acaben interfiriendo en el conjunto de resultados que esperamos. Además, claro, evitamos que el SQL Server tenga que enviarnos información de los resultados que produce tras cada instrucción, lo que puede llegar a aliviar la carga a la que es sometida el servidor o la red en la cual está actuando.
Así que, ya sabes, no te olvides de ponerlo en ninguno de tus triggers y procedimientos almacenados.
Entre las muchas instrucciones de configuración que nos ofrece Microsoft SQL Server, hay una cuyo uso no parece aportar demasiado, pero que es vital si no queréis enfrentaros a "fenómenos paranormales" en algunas de vuestras queries.
Se trata de SET NOCOUNT ON
Activar esta opción (el ON del final es lo que la activa), equivale a decirle al servidor de base de datos que no queremos que nos devuelva le número de filas afectadas por las instrucciones ejecutadas.
Este comportamiento, que podemos observar normalmente cuando ejecutamos cualquier consulta sobre el Management Studio, afecta a SELECT, DELETE, INSERT y UPDATE. Tras ejecutar cualquiera de estas instrucciones, podemos observar como SQL Sever nos indica el número de filas afectadas por la instrucción.
Pero, ¿qué ocurre si ante cualquiera de las tres anteriores que modifican datos (DELETE, INSERT, UPDATE) se ejecuta detrás algún trigger? La respuesta es fácil: SQL nos devuelve por separado el número de filas afectadas por la instrucción principal (la llamante) y la(s) que se encuentra(n) en el trigger.
Para evitar que SQL Server nos devuelva el conjunto de filas afectadas por cualquier instrucción o query escrita en el trigger, sólo debemos añadir nuestro citado SET NOCOUNT ON al principio de la definición del mismo. Lo mismo es válido para procedimientos almacenados.
De esta forma, dejaremos de recibir el resultado de las filas afectadas. Evidentemente, su utilidad va más allá que la mera información que dejamos de ver en el Management Studio. Su utilidad principal reside en evitar que esta información altere con el conjunto de resultados que queremos que SQL Server nos devuelva.
Así, si ejecutamos una query desde cualquier aplicación, tras la que se acaban ejecutando triggers, la no inclusión de SET NOCOUNT ON en la definición del trigger (En ADO/C++ se actualizan los campos de tipo image o ntext mediante SELECT) o procedimiento almacenado hará que los resultados que obtengamos con la SELECT no sean los esperados y, muy probablemente, nos causen un error.
La magia del SET NOCOUNT ON es, pues, que evitamos que consultas "escondidas" acaben interfiriendo en el conjunto de resultados que esperamos. Además, claro, evitamos que el SQL Server tenga que enviarnos información de los resultados que produce tras cada instrucción, lo que puede llegar a aliviar la carga a la que es sometida el servidor o la red en la cual está actuando.
Así que, ya sabes, no te olvides de ponerlo en ninguno de tus triggers y procedimientos almacenados.
ok, muy bien explicado
ResponderEliminarMuchas gracias por tu comentario, Javier.
EliminarSaludos
Muchas gracias por darse el tiempo de explicarlo tan claramente! :)
ResponderEliminarA ti por tu comentario.
EliminarSaludos
Añadir lo siguiente en el comentario:
ResponderEliminarLa función @@ROWCOUNT se actualiza incluso cuando SET NOCOUNT es ON.
he leído muchos de tus articulos y quiero felicitarte por tan excelente forma de darte a explicar ... muchas gracias por compartir tus conocimiento y de antemano gracias por las futuras.
ResponderEliminarHola, Wilmar:
EliminarMuchísimas gracias a ti por tus amables palabras.
Tu comentario me anima a seguir intentado explicar nuevas cosas.
Gracias.
Gracias , nadie me lo habia explicado tan simple despues de años de ver esta instruccion al fin se que es.
ResponderEliminarDe nada!
EliminarGracias
ResponderEliminarDe nada:)
EliminarHola!. Una consulta, el "set nocount on" aplica para una función SQL Server?, o solo es para triggers y procedimientos almacenados?.
ResponderEliminarHola, Hernan:
EliminarEn funciones no tiene utilidad, ya que una función no puede modificar datos y no devuelve resultados intermedios. Es más, si lo intentas usar, te dará un error.
Gracias por tu pregunta. Es muy interesante.
Saludos.
Excelente explicación
ResponderEliminarGracias!
EliminarMuchas gracias! Jaime
ResponderEliminarSaludos
Muy bien explicado, pero faltó que colocaras un pequeño ejemplo
ResponderEliminarGracias, ¡tomo nota! :)
EliminarMuy buena explicación, muchas gracias.
ResponderEliminarGracias a ti, Rafa.
EliminarExcelente explicación.
ResponderEliminarSaben si hay alguna implicación de no poner la clausula SET NOCOUNT OFF
ResponderEliminar