19 enero 2013

Asignar el valor de una variable desde una consulta

Una operación normal dentro de funciones y procedimientos en SQL Server es asignarle a una variable el resultado de una consulta, existen dos métodos, uno es asignar el valor a la variable directamente dentro de la consulta:


SELECT TOP@var1 = EmployeeID FROM dbo.Employees WHERE LastName = ''


El otro método es usando la instrucción SET


SET @var1 =  (SELECT TOP 1 EmployeeID FROM dbo.Employees WHERE LastName = '')


El problema que suele presentarse es que los dos métodos tienen diferente manera de comportarse en lo que se refiere al valor de la variable si la consulta no retorna ningún resultado, si revisamos el primer caso y partiendo de que la consulta no retorna ningún valor (base de datos Northwind)


DECLARE @var1 INT

SET @var1 = 0

SELECT TOP 1 @var1 = EmployeeID FROM dbo.Employees WHERE LastName = ''

SELECT @var1


El resultado es:



-----------
0

(1 row(s) affected)


Esto quiere decir que conserva el valor que se le asigno a la variable antes de usarla en la consulta, si revisamos el otro método:


SET @var1 = 0

SET @var1 =  (SELECT TOP 1 EmployeeID FROM dbo.Employees WHERE LastName = '')

SELECT @var1


el resultado es:



-----------
NULL

(1 row(s) affected)


Esto es, aun cuando a la variable se le asigno el valor 0 al inicio, al momento de la segunda asignación y ya que esta consulta no retorna ningún valor, SQL Server la cambia a NULL


Conocer esto y tenerlo en cuenta nos ayudara a impedir posibles errores, una forma es nunca dejar de usar el ISNULL en el manejo de nuestras variables asignando valores default cuando sea posible.

Espero que sea de tu interés o que te haya ayudado a solucionar algun problema que se te este presentando

15 enero 2013

Determinar cuantos registros tiene una tabla de SQL server

y ,de paso, como mejorar los tiempos de consulta.


Saber cuantos detalles se encuentran insertados en una tabla en SQL Server es una operación que hacemos por diferentes motivos, generar estadísticas para el usuario o hacer una validación, por ejemplo.

Hacer el conteo del total de registros de una tabla en especifico se puede hacer con la instrucción COUNT(*)

Ejemplo, dada una tabla con nombre registros lanzamos la consulta


SELECT COUNT(*) FROM dbo.registros


Esto nos retornara la cantidad de elementos, en este ejemplo 100,000 detalles















Hasta aquí todo es perfecto, sin embargo, como maniáticos de la mejora de nuestro sistema nos encontramos que este tipo de consultas es Lento con L mayúscula,  si estamos generando este tipo de consultas sobre tablas realmente grandes nos estaremos encontrando con que generamos una carga a nuestro motor de base de datos.

Entonces nos preguntamos, como agilizar esto?, pues si no necesitas el resultado exacto el 100 % del tiempo (bajo algunas circunstancias algo excepcionales puede diferir), nos aprovechamos de la tabla    sysindexes en donde se almacena la columna rows  con la cantidad de detalles, si hacemos las consultas:


SELECT COUNT(*) FROM dbo.registros

SELECT TOP 1 rows FROM sysindexes
INNER JOIN sys.sysobjects ON sys.sysindexes.id = sys.sysobjects.id
WHERE sys.sysobjects.xtype = 'U' AND sys.sysobjects.name = 'registros'
ORDER BY sysindexes.indid


Nos genera el mismo resultado:












Con una gran diferencia, si miramos el Execution plan de estas dos consultas los notamos




























95% contra el 5% del tiempo total de consulta, una gran diferencia que nos ayudara a acelerar nuestros procesos

Espero te sirva el  truco y te ayude en lo que estés desarrollando