UTNianos

Versión completa: [Aporte][Gestión de Datos][Final] 07/02/2017
Actualmente estas viendo una versión simplificada de nuestro contenido. Ver la versión completa con el formato correcto.
Páginas: 1 2
Buenas gente, les dejo lo que me acuerdo del final de gestión que tomaron hoy. Cualquier cosa si alguno se acuerda algo más o ve algo para corregir avise.
El final lo preparé haciendo varios de los subidos acá y con los resúmenes que andan dando vueltas. Les dejo el de hoy.

Teoría
1)a) En caso de no querer eliminar registros de una tabla de audtoría, podría definirse un trigger para que lo impida.
1)b) La cantidad de nodos de los árboles de expresión es siempre par.

2)a) Definir el concepto de transacción de un Sistema de Base de Datos.
2)b) Qué significan las siglas ACID. Desarrolle el concepto de cada una de ellas.

Práctica
3a) Daban dos tablas, una de usuarios y otras de ingresos. Era sobre un sistema de logueo de usuario (si un usuario había ingresado alguna vez, aparecía en ingresos, sino significaba que la fecha de ingreso era la de alta del mismo)

Usuarios
IdUsuario int (pk)
nombre varchar(30) not null
apellido varchar(30) not null
fechaAlta date not null

Ingresos
IdUsuario int (fk)
fecha date not null


Justamente daban una vista y había que elegir alguna de las siguientes opciones. La vista debía cumplir con eso que puse, es decir, devolver los usuarios que hayan ingresado alguna vez con su respectiva fecha y los que nunca ingresaron, que figure la fecha de alta del usuario. Cualquiera de las fechas que se tratara, debía deolverse en el campo ultimoIngreso.


CREATE VIEW vw_final(nombre, apellido, ultimoIngreso) AS
SELECT nombre, apellido, MAX(fecha) FROM ingresos i, usuarios
WHERE i.idUsuario = usuarios.idUsuario
GROUP BY usuarios.idUsuario, apellido, nombre
UNION
SELECT nombre, apellido, fechaAlta FROM usuarios

Las opciones no las recuerdo bien pero eran similares a las siguientes:
I. La vista se ejecuta y trae lo pedido.
II. La vista se ejecuta y no trae lo pedido.
III. La vista se crea y no se ejecuta.
IV. La vista no se puede crear.

3)b) Nos decían que se querían eliminar registros de la tabla usuarios y que al ejecutar un DELETE FROM usuarios WHERE idUsuario = 8 tiraba un error. Explicar el motivo de la falla y crear el/los objetos necesarios para poder hacer correr esa sentencia.


En cuanto a las respuestas:
1) a) Verdadero.
1) b) Falso.

2)a) y b) Son preguntas que están en cualquiera de los apuntes del foro. Hasta los mismos apuntes de cátedra lo explican de punta a punta. Las transacciones son un conjunto de sentencias que se ejecutan atómicamente (como una unidad) y pasan de un estado correcto a otro estado correcto, no permitiendo que queden datos inconsistentes. También expliqué lo que hacían el commit y el rollback. En fin, todo lo relacionado a transacciones. En cuanto a las siglas ACID había que explicar cada una de ellas: Atomicidad, Consistencia, Aislamiento, Durabilidad.


3)a) Este punto lo hice mal, pero la verdad me descolocó el dudar si la vista se llegaba a crear o no (porque tengo entendido que la cláusula UNION no es válida)

3)b) Había que hacer un trigger de instead of delete que borre en cascada, es decir, primero que se fije si el idUsuario existía en la tabla ingresos para borrarlo previamente, y luego en usuarios
Espero no burrearla... pero el union está bien, la cantidad de columnas y tipos de datos coinciden.
La vista se crea pero no devuelve lo pedido... porque si el usuario ya está dado de alta y tiene ingresos... va a devolver 2 filas, el ALTA y el último ingreso... creooooooooooooo
Hola... yo lo rendi... me saque 9.

hice lo q dicen arriba...

1) a) Verdadero.
1) b) Falso.

2)a) y b) de los resumenes

3)a) puse la opcion 2. II. La vista se ejecuta y no trae lo pedido. como dice orekav "porque si el usuario ya está dado de alta y tiene ingresos... va a devolver 2 filas, el ALTA y el último ingreso"
para corregir eso puse en la 2da mitad un where not exists (select 1 from ingresos where idusuaio = u.idusurio)

3)b) quiza ahi la lime un poco.
puse q pinchaba por q existia una fk. y q lo resolvia cambiando la fk para q en el delete ponga en null los hijos.
me pidieron q ponga el codigo mediante el cual cambiaba la fk. lo puse a medias...

por las dudas tb hice el trigger como dice Feche pero todo en un pseudocodigo...

creo q no fue dificil de los dificiles... tuve suerte!!!
Buenas!
Bastante accesible, por lo que veo.

La verdad lo del UNION en la vista me descoloca, porque por todos lados dice que no se admite. Cual seria la excepcion?
Ese lo tomaron en otro final

Ahora si pidiera hacer un query que funcione , creo que esta seria una alternativa, aunque no estoy seguro.



SELECT Usuario.Nombre, Usuario.Apellido,
CASE WHEN (EXISTS SELECT Ingresos.UsuarioID FROM Ingresos WHERE Ingresos.UsuarioID = Usuario.UsuarioID) THEN SELECT MAX(Fecha) FROM Ingresos
WHERE Ingresos.UsuarioID = Usuario.UsuarioID ELSE Usuario.FechaAlta END

FROM Usuario

(08-02-2017 14:42)lianndt escribió: [ -> ]Buenas!
Bastante accesible, por lo que veo.

La verdad lo del UNION en la vista me descoloca, porque por todos lados dice que no se admite. Cual seria la excepcion?
Ese lo tomaron en otro final

Ahora si pidiera hacer un query que funcione , creo que esta seria una alternativa, aunque no estoy seguro.


SELECT Usuario.Nombre, Usuario.Apellido, CASE WHEN (EXISTS SELECT Ingresos.UsuarioID FROM Ingresos WHERE Ingresos.UsuarioID = Usuario.UsuarioID) THEN SELECT MAX(Fecha) FROM Ingresos WHERE Ingresos.UsuarioID = Usuario.UsuarioID ELSE Usuario.FechaAlta END

FROM Usuario


Siempre se puede en vistas los unions. Lo que no podes es darle un orden a cada select, eso te rompe.

Respecto a la consulta, otra alternativa posible es:


SELECT U.Nombre, U.Apellido, ISNULL(MAX(I.FECHA),U.FECHAALTA) FECHA FROM INGRESOS I
RIGHT JOIN USUARIOS U
ON I.USUARIOID = U.USUARIOID
GROUP BY U.USUARIOID,U.NOMBRE, U.APELLIDO,U.FECHAALTA


(08-02-2017 15:25)Martin. escribió: [ -> ]
(08-02-2017 14:42)lianndt escribió: [ -> ]Buenas!
Bastante accesible, por lo que veo.

La verdad lo del UNION en la vista me descoloca, porque por todos lados dice que no se admite. Cual seria la excepcion?
Ese lo tomaron en otro final

Ahora si pidiera hacer un query que funcione , creo que esta seria una alternativa, aunque no estoy seguro.


SELECT Usuario.Nombre, Usuario.Apellido, CASE WHEN (EXISTS SELECT Ingresos.UsuarioID FROM Ingresos WHERE Ingresos.UsuarioID = Usuario.UsuarioID) THEN SELECT MAX(Fecha) FROM Ingresos WHERE Ingresos.UsuarioID = Usuario.UsuarioID ELSE Usuario.FechaAlta END

FROM Usuario


Siempre se puede en vistas los unions. Lo que no podes es darle un orden a cada select, eso te rompe.

Respecto a la consulta, otra alternativa posible es:


SELECT U.Nombre, U.Apellido, ISNULL(MAX(I.FECHA),U.FECHAALTA) FECHA FROM INGRESOS I
RIGHT JOIN USUARIOS U
ON I.USUARIOID = U.USUARIOID
GROUP BY U.USUARIOID,U.NOMBRE, U.APELLIDO



Yo la verdad pensé q no se podía. En algún lado leí como que no era posible usar el union, pero lo probé y funciona. Yo quise hacer algo parecido pero no me acordé el ISNULL.
Hice un LEFT JOIN porq las escribí al revés las tablas, y quería aplicar algo similar al ISNULL que no podía acordármelo jaja. En fin, a mi se me ocurrió eso mismo pero no lo pude hacer porque no me acordaba el ISNULL.
La solucion de Martin es mas performante creo yo, porque no tenes subselects y aprovechas el join directamente.

En cuanto al trigger yo haria algo asi:


CREATE TRIGGER Trig_Usuario ON Usuario
INSTEAD OF DELETE

AS
BEGIN

DELETE Ingresos FROM Ingresos i INNER JOIN deleted d ON d.UsuarioID = i.UsuarioID
DELETE Usuario FROM Usuario u INNER JOIN deleted d ON u.UsuarioID = d.UsuarioID



Entonces ahi te aseguras de barrer primero todos los FK antes de volar los PK. Otra seria tirando algun IF, pero no hace falta porque el primer delete no tira error si es que el usuario no tiene ingresos, no borra nada y listo.


creeeo que seria asi , despues lo pruebo.
En el pdf "objetos de una BD v5" pag 18, restricciones "No es posible adicionar a una View las cláusulas de: ORDER BY y UNION."
Ojo chicos, probando en esta web se puede ver como si acepta el UNION en la view y que la misma se crea pero al ejecutarla no trae lo solicitado, como decian mas arriba.

Saludos!

[attachment=16152]
(07-02-2018 18:44)xavi82 escribió: [ -> ]Ojo chicos, probando en esta web se puede ver como si acepta el UNION en la view y que la misma se crea pero al ejecutarla no trae lo solicitado, como decian mas arriba.

Saludos!

Entiendo que no se refiere al momento de la creación, sino al momento de consultar. Probá usar UNION u ORDER BY en la consola de la derecha, donde hacés el SELECT a la vista.
(08-02-2017 17:59)lianndt escribió: [ -> ]La solucion de Martin es mas performante creo yo, porque no tenes subselects y aprovechas el join directamente.

En cuanto al trigger yo haria algo asi:

CREATE TRIGGER Trig_Usuario ON Usuario
INSTEAD OF DELETE

AS
BEGIN

DELETE FROM Ingresos i INNER JOIN deleted d ON d.UsuarioID = i.UsuarioID
DELETE FROM Usuario u INNER JOIN deleted d ON u.UsuarioID = d.UsuarioID


Entonces ahi te aseguras de barrer primero todos los FK antes de volar los PK. Otra seria tirando algun IF, pero no hace falta porque el primer delete no tira error si es que el usuario no tiene ingresos, no borra nada y listo.


creeeo que seria asi , despues lo pruebo.

Yo lo hice de esta manera, lo probe y funciono:



CREATE TRIGGER borrar_usuarios ON Usuarios INSTEAD OF DELETE
AS
BEGIN
DELETE FROM Ingresos WHERE IdUsuario IN (SELECT IdUsuario FROM deleted)
DELETE FROM Usuarios WHERE IdUsuario IN (SELECT IdUsuario FROM deleted)
END

(07-02-2018 17:29)CarooLina escribió: [ -> ]En el pdf "objetos de una BD v5" pag 18, restricciones "No es posible adicionar a una View las cláusulas de: ORDER BY y UNION."

Los apuntes teóricos de la cátedra respecto a conceptos de bases de datos deja mucho que desear, dado que no aclara para que motor de base de datos es.

En el caso de SQL Server, podes crear vistas con unions, pero no podes darle un order by.

Por ese motivo hay que tomarlo con pinzas eso.

Respecto al trigger está correcto. Otra manera (Si supieramos el nombre de la FK) era meter un alter table y nocheck constraint.
Cuando lo puse no pense en el motor, pense que siempre hablaban de sql server
Yo tambien vi lo que probaron y lo probe por mi cuenta

GRacias!

(12-02-2018 16:02)DaWy escribió: [ -> ]
(08-02-2017 17:59)lianndt escribió: [ -> ]La solucion de Martin es mas performante creo yo, porque no tenes subselects y aprovechas el join directamente.

En cuanto al trigger yo haria algo asi:

CREATE TRIGGER Trig_Usuario ON Usuario
INSTEAD OF DELETE

AS
BEGIN

DELETE FROM Ingresos i INNER JOIN deleted d ON d.UsuarioID = i.UsuarioID
DELETE FROM Usuario u INNER JOIN deleted d ON u.UsuarioID = d.UsuarioID


Entonces ahi te aseguras de barrer primero todos los FK antes de volar los PK. Otra seria tirando algun IF, pero no hace falta porque el primer delete no tira error si es que el usuario no tiene ingresos, no borra nada y listo.


creeeo que seria asi , despues lo pruebo.

Yo lo hice de esta manera, lo probe y funciono:


CREATE TRIGGER borrar_usuarios ON Usuarios INSTEAD OF DELETE
AS
BEGIN
DELETE FROM Ingresos WHERE IdUsuario IN (SELECT IdUsuario FROM deleted)
DELETE FROM Usuarios WHERE IdUsuario IN (SELECT IdUsuario FROM deleted)
END


De esta manera admite un borrado masivo no ?
(12-02-2018 19:43)CarooLina escribió: [ -> ]Cuando lo puse no pense en el motor, pense que siempre hablaban de sql server
Yo tambien vi lo que probaron y lo probe por mi cuenta

GRacias!

(12-02-2018 16:02)DaWy escribió: [ -> ]
(08-02-2017 17:59)lianndt escribió: [ -> ]La solucion de Martin es mas performante creo yo, porque no tenes subselects y aprovechas el join directamente.

En cuanto al trigger yo haria algo asi:

CREATE TRIGGER Trig_Usuario ON Usuario
INSTEAD OF DELETE

AS
BEGIN

DELETE FROM Ingresos i INNER JOIN deleted d ON d.UsuarioID = i.UsuarioID
DELETE FROM Usuario u INNER JOIN deleted d ON u.UsuarioID = d.UsuarioID


Entonces ahi te aseguras de barrer primero todos los FK antes de volar los PK. Otra seria tirando algun IF, pero no hace falta porque el primer delete no tira error si es que el usuario no tiene ingresos, no borra nada y listo.


creeeo que seria asi , despues lo pruebo.

Yo lo hice de esta manera, lo probe y funciono:


CREATE TRIGGER borrar_usuarios ON Usuarios INSTEAD OF DELETE
AS
BEGIN
DELETE FROM Ingresos WHERE IdUsuario IN (SELECT IdUsuario FROM deleted)
DELETE FROM Usuarios WHERE IdUsuario IN (SELECT IdUsuario FROM deleted)
END


De esta manera admite un borrado masivo no ?

No se me ocurrio probar un borrado masivo, por lo que dice el enunciado, pero entiendo que si, seria interesante probarlo
Buenísima tu idea martin !

Agrego:

Si toda la columna es null
- sum, max, min es null
- count es 0

el isnull cualquier cosa que se use y este fuera de group by o funcion de agregado el motor chilla.
Páginas: 1 2
URLs de referencia