Ir al contenido principal

SET NOCOUNT ON

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.

Comentarios

  1. Muchas gracias por darse el tiempo de explicarlo tan claramente! :)

    ResponderEliminar
  2. Añadir lo siguiente en el comentario:
    La función @@ROWCOUNT se actualiza incluso cuando SET NOCOUNT es ON.

    ResponderEliminar
  3. 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.

    ResponderEliminar
    Respuestas
    1. Hola, Wilmar:

      Muchísimas gracias a ti por tus amables palabras.

      Tu comentario me anima a seguir intentado explicar nuevas cosas.

      Gracias.

      Eliminar
  4. Gracias , nadie me lo habia explicado tan simple despues de años de ver esta instruccion al fin se que es.

    ResponderEliminar
  5. Hola!. Una consulta, el "set nocount on" aplica para una función SQL Server?, o solo es para triggers y procedimientos almacenados?.

    ResponderEliminar
    Respuestas
    1. Hola, Hernan:

      En 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.

      Eliminar
  6. Muy bien explicado, pero faltó que colocaras un pequeño ejemplo

    ResponderEliminar
  7. Muy buena explicación, muchas gracias.

    ResponderEliminar
  8. Saben si hay alguna implicación de no poner la clausula SET NOCOUNT OFF

    ResponderEliminar

Publicar un comentario

Entradas populares de este blog

Script para obtener el tamaño de todas las tablas de la base de datos

En algunas ocasiones podemos vernos con la necesidad de conocer qué tablas de nuestra base de datos están ocupando más espacio en disco. Por ejemplo, si disponemos de SQL Server Express , cuyas bases de datos están limitadas a 4GB o 10GB, según la versión que estemos usando -4, hasta 2005; 10, a partir de 2008-, aparte de usar las opciones de comprimir la base de datos, poner el log en el modo simple de recuperación o ajustar las políticas de crecimiento automático de nuestros ficheros, podemos necesitar averiguar qué tablas crecen más para tomar las decisiones oportunas.

Aprendiendo a usar LEFT OUTER JOIN

En esta entrada pretendemos explicar los diferentes resultados obtenidos por distintas construcciones de consultas que, aparentemente, deberían producir el mismo conjunto de resultados. Así, veremos las diferencias entre filtrar los resultados de una query en la unión (Join) mediante condiciones ON y mediante cláusulas WHERE.