El problema era el siguiente: para el desarrollo de un sistema que controla los horarios de clases, los posibles choques de horarios y aulas que pueden existir entre diferentes actividades, es decir, saber cuando se programe el calendario de una actividad no choque con otra actividad ya que esta otra pueda estar usando el mismo aula, a la misma hora en el mismo dia.
Por ejemplo, si ingreso al sistema una actividad "A" que son los lunes, miercoles y viernes de 4pm a6pm del 1 de agosto al 15 de agosto utilizando el aula ABC, al momento que se intente de ingregar una actividad "B" que sean los martes, miercoles y sabados, de 5pm a 7pm utilizando el aula ABC del 10 al 20 de agosto no me permita hacerlo, ya que para la actividad "A" los miercoles cochan una hora en especial (coinciden de 5pm a 6pm) y comparten comparten 5 dias en comun (del 10 al 15 de agosto) y dentro de esos 5 dias hay un miercoles de por medio.
En pocas palabras la sentencia SQL deseada debe tomar encuenta todas estas variables: aula, dia, horas, fechas de duracion de los cursos y determinar si todas estas variables coinciden en algun momento por mas pequeña que sea la coincidencia (el choque).
Googleando un poco no encontre nada, absolutamente nada que me diera una idea, asi que me puse mano a la obra y aqui esta un store procedure que logra esto. El secreto esta en determinar dichos choques al momento de que definimos cada uno de los bloque de dias-horas por separados.
Yo poseo una tabla por cada elemento: Aulas, dias, actividad (descripciones de las diferentes actividades), actividad-calendario-encabezado (donde asigno la actividad y la fecha de duracion) y actividad-calendario-detalle (donde asigno los dias, el aula y las horas a cada renglon)
La horas debe ser en formato militar, es decir 12, 13, 14, etc., en vez de usar 12pm, 1pm, 2pm. De esta forma podemos crear el campo de hora como tipo numeric(4,3) para lograr nuestros objetivos.
CREATE PROCEDURE [dbo].[sp_horario_aula_choque]
@dia tinyint,
@aula int,
@ini numeric(4,2),
@fin numeric(4,2),
@fini datetime,
@ffin datetime
AS
BEGIN
SET NOCOUNT ON;
select * from dbo.vw_horario_aula_choque where aula_id = @aula and dia_id = @dia and
((@ini >= det_hini and @ini <> det_hini and @fin <>
(@ini <= det_hini and @fin >= det_hfin)) and
((@fini >= enc_fhinicio
and @fini <= enc_fhfinal) or (@ffin > enc_fhinicio and @ffin <= enc_fhfinal)
or (@fini <= enc_fhinicio and @ffin >= enc_fhfinal))
END
vw_horario_aula_choque es una vista que contiene la relacion de todas las tablas ya mencionadas.
Si el store procedure devuelve algun resultado existe un choque y este sera lo que nos presentara el SP.
Especialista en Programacion .Net C#, PHP, Delphi, amante de Firebird y FreeBSD.
Mostrando entradas con la etiqueta sql server. Mostrar todas las entradas
Mostrando entradas con la etiqueta sql server. Mostrar todas las entradas
sábado, 23 de agosto de 2008
martes, 7 de agosto de 2007
Restaurar base de datos a partir de un MDF
Nueva situacion:
Varias base de datos estaban utilizando varios filegroup para almacenar los indices, dichos filegroups estaban ubicados en discos diferentes al MDF, y el archivo de log de transacciones de todas las bases de datos tambien estaban en discos diferentes.
Resulta ser que el disco que contenia los filegroups y los log de transacciones se perdio, unicamente quedaron los MDF solos y no existian backups.
Cuando trataba de hacer un simple attach a las base de datos, el servidor SQL Server 2005 buscaba los archivos asociados a el (los filegroups y logs) en las mismas ubicaciones que estaban (ubicaciones y archivos que ya no existian) y al no encontrar nada no me dejaba atacharlas.
Mi razonamiento era el siguiente: en los filegroups (.NDF) solo estaba almacenando los indices, los log de transacciones se reconstruyen cuando estos se pierden o se corrompen. Y lo que me quedaba en las manos eran los MDF que son los que contienen la data real, los registros y las tablas, pues teoricamente tenia en mis manos lo que realmente importaba.
El hecho es que intente todo y nada fue posible, pase varios dias buscando informacion en el MSDN, en foros sobre el tema... y no hay solucion cuando se pierden los filegroup asociados a la DB, aunque no lo utilices y no contengan nada.
En resumen, NUNCA TE DESCUIDES CON LOS BACKUP, es la unica garantia segura con SQL Server de recuperar informacion, olvidate de que tienes el log de transacciones, el MDF, porque nada es seguro.
Varias base de datos estaban utilizando varios filegroup para almacenar los indices, dichos filegroups estaban ubicados en discos diferentes al MDF, y el archivo de log de transacciones de todas las bases de datos tambien estaban en discos diferentes.
Resulta ser que el disco que contenia los filegroups y los log de transacciones se perdio, unicamente quedaron los MDF solos y no existian backups.
Cuando trataba de hacer un simple attach a las base de datos, el servidor SQL Server 2005 buscaba los archivos asociados a el (los filegroups y logs) en las mismas ubicaciones que estaban (ubicaciones y archivos que ya no existian) y al no encontrar nada no me dejaba atacharlas.
Mi razonamiento era el siguiente: en los filegroups (.NDF) solo estaba almacenando los indices, los log de transacciones se reconstruyen cuando estos se pierden o se corrompen. Y lo que me quedaba en las manos eran los MDF que son los que contienen la data real, los registros y las tablas, pues teoricamente tenia en mis manos lo que realmente importaba.
El hecho es que intente todo y nada fue posible, pase varios dias buscando informacion en el MSDN, en foros sobre el tema... y no hay solucion cuando se pierden los filegroup asociados a la DB, aunque no lo utilices y no contengan nada.
En resumen, NUNCA TE DESCUIDES CON LOS BACKUP, es la unica garantia segura con SQL Server de recuperar informacion, olvidate de que tienes el log de transacciones, el MDF, porque nada es seguro.
viernes, 3 de agosto de 2007
Encriptar clave en SQL Server 2005
Buscando el google encontre varias opciones para encriptar un campo, pero el que me resulto mas facil y comodo de usar fue la funcion pwdencryp(campo), devuelve una cadena encryptada.
Lo que deseaba hacer era encriptar todas las claves de la tabla de usuarios de un sistema que trabajo habitualmente, aqui doy los pasos para lograr tal objetivo:
1. Lo primero es cambiarle el tipo de dato al campo de la clave de varchar(longitud) a varbinary(256), pero antes de esto, tenemos que guardar nuestras claves viejas sin encriptar en un campo temporal para no perder la informacion de la claves de los usuarios.
Cree un campo tiempo llamado "temp", luego pasamos las claves sin encriptar a dicho campo:
alter table usuarios add temp varchar(20)
go
update usuarios set temp = clave
go
2. Cambiar el tipo de dato al campo clave
alter table usuarios alter column clave varbinary(256)
3. Pasando las claves encriptadas a nuestro campo y eliminando el campo temporal
update usuarios set clave = pwdencryp(temp)
go
alter table usuarios drop column temp
go
4. Validando nuestro usuario por medio de una consulta
select * from usuarios where login = @login and pwdcompare(@clave, clave, 0) = 1
si no devuelve ningun registro es porque el usuario o la clave son incorrectas.
Lo que deseaba hacer era encriptar todas las claves de la tabla de usuarios de un sistema que trabajo habitualmente, aqui doy los pasos para lograr tal objetivo:
1. Lo primero es cambiarle el tipo de dato al campo de la clave de varchar(longitud) a varbinary(256), pero antes de esto, tenemos que guardar nuestras claves viejas sin encriptar en un campo temporal para no perder la informacion de la claves de los usuarios.
Cree un campo tiempo llamado "temp", luego pasamos las claves sin encriptar a dicho campo:
alter table usuarios add temp varchar(20)
go
update usuarios set temp = clave
go
2. Cambiar el tipo de dato al campo clave
alter table usuarios alter column clave varbinary(256)
3. Pasando las claves encriptadas a nuestro campo y eliminando el campo temporal
update usuarios set clave = pwdencryp(temp)
go
alter table usuarios drop column temp
go
4. Validando nuestro usuario por medio de una consulta
select * from usuarios where login = @login and pwdcompare(@clave, clave, 0) = 1
si no devuelve ningun registro es porque el usuario o la clave son incorrectas.
Suscribirse a:
Entradas (Atom)