martes, 16 de febrero de 2010

Visual Studio 2005 y 2008 - Limpiar lista de proyectos recientes

Clean up Visual Studio's Recent Project List Algunos frecuentemente revisamos y/o damos mantenimiento a diferentes proyectos. Cada que abrimos un nuevo en el IDE de Visual Studio, estos se guardan en la lista de proyectos abiertos recientemente. En ocasiones esto es muy bueno, ya que nos ayuda a acceder a un proyecto más rapidamente solo dando clic en (File->Recent Project/Solution) o en la opción Recent Projects del menú de la Start Page de VS. También en ocasiones requerimos eliminar algunas de estas entradas, para ello podemos seguir los siguientes pasos:
  • Acceder al registro de windows (Incio->Run)
  • luego escribimos: regedit
  • oprimimos la tecla enter
  • Navegamos en el regedit para buscar la siguiente entrada para Visual Studio 2008: HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\9.0\ProjectMRUList
  • Para Visual Studio 2005 es la siguiente ruta HKEY_CURRENT_USER\Software\Microsoft\VisualStudio\8.0\ProjectMRUList
y ahora sí, aquí tenemos las entradas a los diferentes proyectos abiertos, los cuales podemos editar, eliminar o cambiar de precedencia.
Nota: Si eliminas elementos o cambias de orden, es importante renombrar los demas, de forma que siempre queden, File1, File2, File3, File4...

martes, 15 de mayo de 2007

Función de agrupación Group and agregación Sum en SQL

Las funciones de agrupación y agregación operan sobre conjuntos de filas para dar un resultado por grupo.

GROUP BY permite agrupar informacion por columnasSUM suma los valores

Mediante la clausula GROUP BY se dividen las filas que devuelve una consulta en pequeños grupos. Cuando hagamos uso de esta clausula hay que tener en cuenta que todas las columnas que pongamos en el SELECT y que NO estén en la cláusula GROUP BY, deberán estar en una función de agrupación.

==INCORRECTO==
SELECT FECHA, MONTOFROM INGRESOS
GROUP BY FECHA

==CORRECTO==
SELECT FECHA, SUM (MONTO)
FROM INGRESOS
GROUP BY FECHA

A Continuación un ejemplo de como podemos obtener los ingresos generados por cada uno de los conceptos correspondientes a cada dia.


================================================
==TABLA INGRESOS==
FECHA CONCEPTOID NOMBRE MONTO
2/16/2007 9 DONATIVOS 1000.00
2/28/2007 4 VENTAS 100.00
2/22/2007 9 DONATIVOS 120.00
2/22/2007 9 DONATIVOS 250.00
2/22/2007 4 VENTAS 100.00
2/23/2007 9 DONATIVOS 120.00

================================================
==SENTENCIA==
SELECT FECHA, CONCEPTOID, NOMBRE, SUM(MONTO)
FROM INGRESOS
GROUP BY FECHA, CONCEPTOID, NOMBRE
ORDER BY FECHA

==RESULTADO==
FECHA CONCEPTOID NOMBRE MONTO
2/16/2007 9 DONATIVOS 1000.00
2/22/2007 4 VENTAS 100.00
2/22/2007 9 DONATIVOS 370.00
2/23/2007 9 DONATIVOS 120.00
2/28/2007 4 VENTAS 100.00

Como podemos observar para este caso sencillo, habia dos ingresos por concepto de DONATIVOS en una misma fecha 2/22/2007, y en nuestra consulta se suman ambos registros mediante el uso de la agrupación y agregación.

viernes, 20 de abril de 2007

AJAX Load

Un generador de imagenes de Carga?? Si, Ajax Load es un generador de imágenes animadas de carga que dan la impresión de movimiento, mientras que se está cargando algún contenido o se está realizando una acción. Simplemente seleccionas los colores, el tipo de imágen que quieres utilizar y listo.

jueves, 22 de febrero de 2007

SQL - Obtener registros que se encuentren en un rango de fechas (Fecha inicial y Fecha Final)

Es algo comun sobre todo al momento de realizar reportes, el querer obtener registros que se encuentren en un determinado rango de fechas. Existen varias formas de realizarlo, a continuacion un ejemplo sencillo de como podemos llevar acabo esta operacion. En este ejemplo, deseamos obtener todos los registros del 16 de enero al 15 de febrero, incluyendo estos dias.

Si las fechas que deseamos comparar son de tipo DateTime debemos tener en cuenta que las fechas incluyen Dia, Mes, Anyo, Minutos, Segundos y Milisegundos. De esa forma, una fecha '15-02-2007 59:59.998' es valida para nuestra consulta.



-- Declaramos las fechas inicial y final respectivamente
DECLARE @FechaInicial AS DATETIME
DECLARE @FechaFinal AS DATETIME

-- Asignamos las fechas (Pueden ser recibidas en un
--stored procedure)
SET @FechaInicial = '16-01-2007 00:00'
SET @FechaFinal = '15-02-2007 00:00'

--========================================================
-- Si los valores son recibido en un Stored, es necesario
-- verificar que realmente queden en el formato anterior.
SET @FechaInicial = CONVERT(VARCHAR,@FechaInicial, 105) + ' 00:00'
SET @FechaFinal = CONVERT(VARCHAR, @FechaFinal, 105) + ' 00:00'
--========================================================

-- A la fecha final le sumamos un 1 dia, y obtenemos todas
-- las fechas que sean igual o mayor a '16-01-2007 00:00'
-- y sean menores a '16-02-2007 00:00'.
-- Mucho cuidado, ya que si la @FechaFinal tiene siquiera
-- milisegundos, podemos llegar a obtener registros no deseados.

SELECT *
FROM TuTabla AS T
WHERE (T.Fecha >= @FechaInicial AND T.Fecha < DATEADD(DAY, 1, @FechaFinal))

martes, 16 de enero de 2007

SQL - Recomendaciones

Recomendaciones para su uso en SQL:
  • No hacer uso de sp_ al inicio de los procedimientos almacenados.
  • Cuando realicemos consultas, hacer uso de WITH(NOLOCK) para no bloquear las tablas inecesariamente.
  • Utilizar parámetros de entrada y de salida para procedimientos almacenados.
  • Hacer uso de RETURN cuando vayamos a regresar un valor entero, en lugar de develver ese valor mediante un SELECT.
  • Utilizar transacciones y controlar los errores en los procedimientos almanacenados.
  • Emplear errores personalizados.
Las anteriores son solo recomendaciones y se debe analizar en que momento hacer uso de las mismas.

SQL - Eliminar multiples registros de una tabla.

SQL - Eliminar multiples registros de una tabla. Muchas veces requerimos eliminar más de un registro y que estos cumplan con una serie de requerimientos. Imaginense tener que eliminar más de 10,000 registros pero que estos cumplan con ciertas especificaciones, para lo cual tenemos que consultar más de dos tablas. Si lo quisieramos realizar de la manera tradicional, es decir, eliminar registro por registro, es seguro que nos llevaria muchisimo tiempo. Una forma rápida, fácil y segura de eliminar los registros es seguir los siguientes pasos: Ejemplo: Si desearamos eliminar todos los Usuarios de TipoUsuario A y B que pertenezcan a la Empresa 5.
  • 1.- Crear nuestra consulta de los registros que deseamos eliminar. Aqui estamos no estamos considerando que otras tablas hagan referencia a los valores que deseamos eliminar. [Verificar que realmente sean los registros que deseamos eliminar]. Si la consulta es muy compleja o se desea hacer en secciones, puede hacerse uso de tablas temporales para almacenar por ejemplo, los Ids de los registros a eliminar, y posteriormente hacer uso de esa tabla temporal como parte de la restriccion para la eliminacion.d
SELECT * FROM Usuario U INNER JOIN Departamento D ON U.DepartamentoId=D.DepartamentoId INNER JOIN Empresa E ON D.EmpresaId=E.EmpresaId WHERE E.EmpresaId=5 AND U.TipoUsuario IN ('A','B')
  • 2.-Creamos una transaccion.
BEGIN TRAN
  • 3.- Procedemos a eliminar los registros.
DELETE Usuario -- SELECT * FROM Usuario U INNER JOIN Departamento D ON U.DepartamentoId=D.DepartamentoId INNER JOIN Empresa E ON D.EmpresaId=E.EmpresaId WHERE E.EmpresaId=5 AND U.TipoUsuario IN ('A','B')
  • 4.- Verificamos que el total de lineas afectadas hayan coincidan con el total de registros obtenidos en la consulta del paso 1.
Si estamos seguros de eliminar los registros, realizar el commit de la transaccion COMMIT TRAN Si no estamos seguros o sucedio un error, realizamos un rollback a la transaccion ROLLBACK TRAN

viernes, 10 de noviembre de 2006

SQL - Medir el tiempo de ejecución de sentencias sql

Algo muy útil para cuando tenemos diversas formas de solucionar un problema en SQL y desconocemos cual de ellas será la más rápida (no necesariamente la más optima) es medir el tiempo de ejecución de cada una de ellas y de esa forma poder seleccionar la solución más rápida.

--Declaracion de la variable que nos permitira medir el tiempo DECLARE @TiempoInicial DATETIME SET @TiempoInicial = GETDATE() -- ------------------------------- SETENCIAS ------------------------------- SELECT * FROM Persona WHERE DATEDIFF(day, FechaRegistro, DATEADD(DAY,-15,GETDATE())) <= 0 -- ------------------------------- SETENCIAS ------------------------------- -- Realizar la diferencia entre el tiempo inicial y final de la ejecución de las sentencias PRINT 'Operacion completada en: ' + RTRIM(CAST(DATEDIFF(ms,@TiempoInicial, GETDATE()) AS VARCHAR(10))) + ' milisegundos'

martes, 7 de noviembre de 2006

SQL - Crear un procedimiento almacenado

En el presente articulo veremos como crear tres tipos de procedimientos almacenados:
  1. Procedimento sin parametros.
  2. Procedimiento con parámetros de entrada.
  3. Procedimiento con parámetros de entrada y de salida. 

Nota: Los procedimientos almacenados definidos por el usuario son creados en la base de datos actual.
Procedimiento sin parámetros.

/* --------------------------------------------------------------------------------
   Autor: Mario Alberto Sanchez Gamboa
   Fecha:
   Descripcion: Procedimiento que realiza la suma de dos numeros y regresa
   el resultado mediante el uso de la sentencia SELECT.
      **Emplea declaracion de variables.
      **Asigacion de valores a variables.
      **Uso de ISNULL.- Remplaza el nulo por el valor especificado.
      **Uso de CAST.- Convierte explicitamente una expresion de un tipo de dato a otro.
      **Concatenacion de cadenas.
   -------------------------------------------------------------------------------- */
CREATE PROCEDURE spSumaSinParametros
AS
   --Declaracion de variables
   DECLARE @Numero1 FLOAT,
      @Numero2 FLOAT,
      @Resultado FLOAT,
      @Operacion NVARCHAR(25)


   --Asignacion de valores iniciales
   SET @Numero1 = 5.55
   SET @Numero2 = 15


   --Operacion.
   --Nota: Se puede hacer uso de SELECT y/o SET para la asignacion de valores a las variables.
   SELECT @Resultado = ISNULL(@Numero1, 0) + ISNULL(@Numero2, 0)
   SET @Operacion = CAST(@Numero1 AS VARCHAR) + ' + ' + CAST(@Numero2 AS VARCHAR) + ' = ' + CAST(@Resultado AS VARCHAR)


   --Realizar un select con el resultado de la operacion.
   SELECT @Numero1 AS Numero1, @Numero2 AS Numero2, @Resultado AS Resultado, @Operacion AS Operacion

GO
Para ejecutar el procedimiento almacenado empleamos la siguiente sentencia:

   EXECUTE spSumaSinParametros

Resultado:

Numero1 Numero2 Resultado Operacion
-------------------- ---------- --------------------- --------------------
5.5499999999999998 15.0 20.550000000000001 5.55 + 15 = 20.55

(1 row(s) affected)
Procedimiento con parámetros de entrada.

/* --------------------------------------------------------------------------------
   Autor: Mario Alberto Sanchez Gamboa
   Fecha:
   Descripcion: Procedimiento que realiza la suma de dos numeros
      los cuales recibe mediante parametros de entrada
      y regresa el resultado mediante el uso de la sentencia SELECT.
      **Emplea declaracion de variables.
      **Asigacion de valores a variables.
      **Uso de ISNULL.- Remplaza el nulo por el valor especificado.
      **Uso de CAST.- Convierte explicitamente una expresion de un tipo de dato a otro.
      **Concatenacion de cadenas.
   -------------------------------------------------------------------------------- */
CREATE PROCEDURE spSumaConParametros
      @Numero1 FLOAT,
      @Numero2 FLOAT
AS
   --Declaracion de variables
   DECLARE
      @Resultado FLOAT,
      @Operacion NVARCHAR(25)


   --Operacion.
   --Nota: Se puede hacer uso de SELECT y/o SET para la asignacion de valores a las variables.
   SELECT @Resultado = ISNULL(@Numero1, 0) + ISNULL(@Numero2, 0)
   SET @Operacion = CAST(@Numero1 AS VARCHAR) + ' + ' + CAST(@Numero2 AS VARCHAR) + ' = ' + CAST(@Resultado AS VARCHAR)


   --Realizar un select con el resultado de la operacion.
   SELECT @Numero1 AS Numero1, @Numero2 AS Numero2, @Resultado AS Resultado, @Operacion AS Operacion
GO
Para ejecutar el procedimiento almacenado empleamos la siguiente sentencia:

   EXECUTE spSumaConParametros 5.55, 15

Resultado:

Numero1 Numero2 Resultado Operacion
-------------------- ---------- --------------------- --------------------
5.5499999999999998 15.0 20.550000000000001 5.55 + 15 = 20.55

(1 row(s) affected)
Procedimiento con parámetros de entrada y salida.

/* --------------------------------------------------------------------------------
   Autor: Mario Alberto Sanchez Gamboa
   Fecha:
   Descripcion: Procedimiento que realiza la suma de dos numeros y regresa
      el resultado mediante el uso un parametro de salida y una sentencia SELECT.
      El valor son recibidos con parametros de entrada, y el resultado es regresado
      mediante un parametro de salida, asi como de una sentencia SELECT.
      **Emplea declaracion de variables.
      **Asigacion de valores a variables.
      **Uso de ISNULL.- Remplaza el nulo por el valor especificado.
      **Uso de CAST.- Convierte explicitamente una expresion de un tipo de dato a otro.
      **Concatenacion de cadenas.
   -------------------------------------------------------------------------------- */
CREATE PROCEDURE spSumaConParametroDeSalida
      @Numero1 FLOAT,
      @Numero2 FLOAT,
      @Resultado FLOAT OUTPUT

AS
   --Declaracion de variables
   DECLARE @Operacion NVARCHAR(25)


   --Operacion.
   --Nota: Se puede hacer uso de SELECT y/o SET para la asignacion de valores a las variables.
   SELECT @Resultado = ISNULL(@Numero1, 0) + ISNULL(@Numero2, 0)
   SET @Operacion = CAST(@Numero1 AS VARCHAR) + ' + ' + CAST(@Numero2 AS VARCHAR) + ' = ' + CAST(@Resultado AS VARCHAR)


   --Realizar un select con el resultado de la operacion.
   SELECT @Numero1 AS Numero1, @Numero2 AS Numero2, @Operacion AS Operacion
GO
Para ejecutar el procedimiento almacenado empleamos la siguiente sentencia:

   DECLARE @ParamResultado FLOAT    DECLARE @EjecucionParametro INT    EXECUTE @EjecucionParametro = spSumaConParametroDeSalida 5.55, 15, @ParamResultado OUTPUT    SELECT @ParamResultado AS Resultado, @EjecucionParametro AS EjecucionParametro

Resultado:

Numero1 Numero2 Resultado Operacion
-------------------- ---------- --------------------- --------------------
5.5499999999999998 15.0 20.550000000000001 5.55 + 15 = 20.55

(1 row(s) affected)

Resultado EjecucionParametro
--------------------- --------------------
20.550000000000001 0

(1 row(s) affected)
Si se desea comprobar la existencia de un procediento se puede hacer uso de las siguientes sentencias.

--Verificamos si el procedimiento que vamos a crear existe en la base de datos,
--en caso de que exista se procede a eliminar dicho procedimiento.
IF EXISTS (SELECT name FROM sysobjects WHERE name = 'spSumaSinParametros' AND type = 'P')
   DROP PROCEDURE spSumaSinParametros
GO
En este ejemplo verificamos si ya existe el procedimiento spSumaSinParametros, en caso de que exista se procede a eliminarlo.

SQL - Conocer si un procedimiento, tabla, etc. existe en la base de datos

Para conocer si un objeto (procedimiento almacenado, constraint, llave foranea, etc.) existe en nuestra base de datos, podemos hacer uso de la tabla del sistema de la base de datos sysobjects en la cual se registran todos los objetos que hemos creados.
A continuación se detalla el diseño de la tabla sysobjects. 
   
Nombre de la columnaTipo de DatoDescripción
namesysnameNombre del objeto.
IdintNúmero de identificación del objeto.
xtypechar(2)Tipo de objeto. Puede ser alguno de los siguientes:

C = CHECK constraint
D = Default or DEFAULT constraint
F = FOREIGN KEY constraint
L = Log
FN = Scalar function
IF = Inlined table-function
P = Stored procedure
PK = PRIMARY KEY constraint (type is K)
RF = Replication filter stored procedure
S = System table
TF = Table function
TR = Trigger
U = User table
UQ = UNIQUE constraint (type is K)
V = View
X = Extended stored procedure

uidsmallintIdentificador del usuario propietario del objeto.
infosmallintReservado. Para uso interno solamente.
statusintReservado. Para uso interno solamente.
base_schema_
ver
intReservado. Para uso interno solamente.
replinfointReservado. Para uso por replicación.
parent_objintNúmero de identificación del objeto padre.
crdatedatetimeFecha en que el objeto fue crado.
ftcatidsmallintIdentifier of the full-text catalog for all user tables registered for full-text indexing, and 0 for all user tables not registered.
schema_verintNúmero de Version la cual es incrementada cada vez que cambia el esquema para un tabla.
stats_schema_
ver
intReservado. Para uso interno solamente.
typechar(2)Tipo de objeto. Puede ser alguno de los siguientes valores:

C = CHECK constraint
D = Default or DEFAULT constraint
F = FOREIGN KEY constraint
FN = Scalar function
IF = Inlined table-function
K = PRIMARY KEY or UNIQUE constraint
L = Log
P = Stored procedure
R = Rule
RF = Replication filter stored procedure
S = System table
TF = Table function
TR = Trigger
U = User table
V = View
X = Extended stored procedure

userstatsmallintReservado.
sysstatsmallintInternal status information.
indexdelsmallintReservado.
refdatedatetimeReservado para uso futuro.
versionintReservado para uso futuro.
deltrigintReservado.
instrigintReservado.
updtrigintReservado.
seltrigintReservado.
categoryintUsado para publicación, identitis (identity) y constraints.
cachesmallintReservado.
 
Ejemplo de uso:

--Verificamos si el procedimiento que vamos a crear existe en la base de datos,
--en caso de que exista se procede a eliminarlo.

IF EXISTS (SELECT name FROM sysobjects WHERE name = 'spProcedimientoABuscar' AND type = 'P' < /FONT > )
   DROP PROCEDURE spProcedimientoABuscar

SQL - Devolver errores y advertencias desde un procedimiento almacenado de SQL Server

En diversas situaciones requerimos poder regresar advertencias o errores personalizados desde un procedimiento almacenado, en el presente articulo veremos como lograrlo.
Si se genera un error en SQL donde su gravedad sea igual o menor a 10 solo se lanza una advertencia sin generar una excepción, sin embargo, si la gravedad fue igual o mayor a 11 es lanzada una excepción y es probable que el procedimiento almacenado sea anulado. Es importante contar también con un manejo de transacciones para que se ejecute o no completo nuestro stored.


/* --------------------------------------------------------------------------------
   Autor: Mario Alberto Sanchez Gamboa
   Fecha:
   Descripcion: Procedimiento que lanza un error personalizado.
   Actualizacion:
   -------------------------------------------------------------------------------- */
ALTER PROCEDURE spTemporal
   @param1 BIT
AS
BEGIN

   IF @param1 = 1
   BEGIN
      RETURN 0
   END
   ELSE
   BEGIN
      RAISERROR ('Error personalizado al momento de ejecutar el procedimiento.', 11, 1)
      RETURN -1
   END

END

Si ejecutamos el stored anterior con un valor de diferente a 1 será lanzado el error personalizado.

EXEC spTemporal 0

Resultado:
Server: Msg 50000, Level 11, State 1, Procedure spTemporal, Line 18
Error personalizado al momento de ejecutar el procedimiento.