Tema5Act6 RodríguezCortesBrendaSoledad

Descargar como pdf o txt
Descargar como pdf o txt
Está en la página 1de 67

INSTITUTO TECNOLÓGICO

DEL VALLE DE OAXACA

TALLER DE BASE DE DATOS

Actividad 5.5 bitácora de avance del proyecto

Integrantes:
Calvo Cruz Axel Jesús
Orozco Vásquez Marco Antonio
Pérez Pacheco Francisco Usiel
Rodríguez Cortes Brenda Soledad.

6° A Ingeniería informática

Docente: Ángeles Pérez Romeo Alberto.

24 de junio de 2021 – Ex hacienda Nazareno Santa Cruz Xoxocotlán.


INTRODUCCIÓN
En el siguiente documento se hace una breve explicación sobre el código desarrollado
durante todo el semestre sobre el proyecto de facturación, como primera parte del desarrollo
tenemos las operaciones básicas con SQL las cuales fueron las siguientes, la inserción de nuevos
registros, modificación de registros, eliminación de registros, la inserción de múltiples registros, al igual
que la creación de índices para las diversas tablas que así lo requieran, como segunda parte se
explicará la creación de usuarios y roles en la base de datos, este tema es fundamental ya que
depende de la seguridad implementarlos correctamente, para ello se elaboran mediante código
SQL.

Asignándole a los usuarios sus diversos permisos, esto con la finalidad de tener un control de las
acciones que puedan realizar, tomando en cuenta los privilegios otorgados, después de eso se
continúa con las vistas, estas son tablas virtuales que almacenan consultas que actúan como filtro
subyacente que se hace referencia a ellas, con su ayuda se puede agrupar diversas tablas,
independientemente de la ubicación de los servidores de consulta, al igual que sirve de consulta en
caso de que no se cuente con la versión similar de SQL, lo que la hace indispensable en la
comprensión y creación de la misma , lo siguiente es el respaldo y recuperación de la base de datos,
el ejemplo a mostrar está hecho con Azure Data Studio, en donde puede variar con otros gestores
de base de datos, sin embargo en una parte también se explica cómo realizarlo mediante SQL, lo
que facilita las cosas, la finalidad de esto es tener un respaldo de la información sobre la que estamos
trabajando para así evitar pérdidas de información y además de esto en caso de tener pérdidas
saber recuperar esa información con la que se ha respaldado, el último a mencionar de la segunda
parte es las transacciones las cuales consisten en un conjunto de acciones que hacen
transformaciones de los estados del sistema para preservar la consistencia del mismo, con su ayuda
y en los ejemplos a mostrar a continuación se mejoran procesos sin la necesidad de intervención
humana, como tercera parte del proyecto tenemos la creación de procedimientos, estos ayudan a
los usuarios a acceder de manera fácil a la base de datos sin tener que conocer los detalles de las
tareas solicitadas, se realiza una breve descripción y por medio de ejemplos se muestra su
funcionamiento e implementación en la base de datos, también se hace mención de los triggers
que como principal función es contribuir a mejorar la gestión de la base de datos permitiendo realizar
operaciones de manera automática, sin necesidad de la intervención humana, lo que facilita el
ahorro de tiempo, este también tiene la ventaja de almacenar los cambios que realice un usuario,
almacenando un registro de las actividades junto a la fecha de la misma.
FACTURACIÓN TECNOLÓGICA
Para la creación de nuestra base de datos se utilizó el sistema de
gestión de bases de datos SQL Server.

Se inicio con la creación de la base de datos, con el nombre de

Facturación tecnológica, utilizando la instrucción Create database

Facturación_tecnologica; como se muestra en la siguiente imagen.

Después ejecutaos la instrucción Use Facturación Tecnologica; Con esa


instrucción estamos indicando que vamos a trabajar dentro de la Base de
datos.
Posteriormente se realizó la creación de las tablas, iniciando con la tabla
“Persona”, donde se asignaron los atributos con sus respectivos tipos, de
datos , tamaños y llaves foráneas, también se especificaron los valores nulos,
como se muestra en la imagen.

Continuamos con la creación de la tabla “Supervisor”, la cual contiene el


atributo Id Supervisor e Id Persona, los cuales son de tipo varchar y de valores
nulos como se observa en la imagen.

Después se creo la tabla “Cliente” donde se establecieron dos atributos de


tipo varchar e indicamos la llave primaria y valores nulos.
Continuamos con la tabla “Dirección” donde se define el id de la dirección
y el id de la calle, por lo que va a contener una llave foránea, que en este
caso es la calle, como se muestra en la imagen.

Después se creó la tabla “Calle” la cual se compone de cuatro atributos,


Esta tabla contendrá los datos de la calle de los clientes, se define el id de
la calle como llave primaria, y el id Asentamiento como llave foránea,
posteriormente el número de calle y finalmente el nombre de la calle, como
se muestra en la imagen.

Posteriormente se creó la tabla “Asentamiento”, donde se definen tres


atributos de tipo varchar y su respectivo tamaño, también se asignó la llave
primaria y los valore nulos, como se observa en la imagen.
Proseguimos creando la tabla “Tipo Asentamiento” donde se asignan dos
atributos de tipo varchar de valores nulos y la llave primaria IdTipoA como se
observa en la imagen.

Después creamos la tabla “Código Postal” la cual contiene tres atributos dos
de tipo varchar y uno de tipo int unique, también se asignó la llave primaria
y los valores nulos.

Continuamos con la tabla “Municipio” donde se asignaron tres atributos de


tipo varchar y su respectivo tamaño también se asigno la llave primaria y los
valores nulos respectivamente, como se observa en la imagen
Proseguimos con la tabla “Cuidad” en la que se asignaron tres atributos de
tipo varchar, la llave primaria y los valores nulos.

Después creamos la tabla “Estado” que contiene tres atributos de tipo


varchar y valor nulo, también se agino la llave primaria, como se observa en
la imagen.

Posteriormente la tabla “País” se establecieron dos atributos de tipo varchar


con valor nulos y la respectiva llave primaria para identificar cada país,
además está el campo país para ingresar el nombre de cada uno de ellos.
Continuamos con la tabla “Modelo” donde se asignaron dos atributos de
tipo varchar con valor nulo, asignando el IdModelo como llave primaria,
como se observa en la siguiente imagen.

Después se creó la tabla “Marca”, que contiene dos atributos de tipo


varchar con valor nulo, también se asigno la llave primaria.

Posteriormente se creo la tabla “Detalle Ticket”, donde se establecieron


cinco atributos con su respectivo tipo y tamaño, como se muestra en la
imagen.

Proseguimos con la tabla “Ticket”, que contiene el id ticket como llave


primaria la fecha de la venta de tipo datatime con valor nulo, y el iva de
tipo float como se observa en la imagen.
Después se creo la tabla “Detalle compra” que contiene cinco atributos
con su respectivo tipo y tamaño de valor nulo, como se observa en la
imagen.

Continuamos con la creación de la tabla “Compra” asignando cuatro


atributos con valores nulos y su respectivo tamaño, como en la imagen.

Después se creo la tabla “Proveedor” con seis atributos de tipo varchar con
su respectivo tamaño y la llave primaria, como en la siguiente imagen.
Proseguimos con la creación de la tabla “Artículos” donde se almacenarán
las características de los artículos cuenta con siete atributos de valor nulo y
la respectiva llave primaria, como se observa en la imagen.

Finalmente se creó la tabla “Factura” que contiene el idFactura de tipo


varchar con valores nulos además se asignó como llave primaria, después
el atributo fechafactura,que es de tipo data time con valor nulo, también el
idCliente de tipo varchar de valor nulo y el idticket de tipo varchar como se
observa en la imagen.
INSERCIÓN DE DATOS
Continuamos con nuestro proyecto con la inserción de datos en las
respectivas tablas, para ello utilizamos la instrucción INSERT que permite
crear o insertar nuevos registros en una tabla.

Iniciamos agregando 5 registros de datos a la tabla “Marca” rellenado los


campos “IdMarca” y “Marca” con la instrucción INSERT INTO Marca VALUES
(‘Ma001’, ‘Vorago’); Como se muestra en la imagen.

Posteriormente insertamos datos en la tabla “Modelo” rellenado los campos


“IdModelo” y “Modelo” utilizando la instrucción INSERT INTO Modelo VALUES
(‘Mo001’, ‘Mm303’); Como se muestra en la imagen.

Continuamos insertando datos en la tabla “Artículos” agregando los


campos “IdArticulo”, “NombreArt”, “Precio”, “Descripción”, “Cantidad”,
“IdMarca” y finalmente “IdModelo”. Como se muestra en la imagen.
Posteriormente se agregaron datos en la tabla “Pais” insertando los campos
“IdPais” y “Pais” utilizando la instrucción INSERT INTO Pais VALUES (‘Pa001’,
‘México’);

Proseguimos insertando datos en la tabla “Estado” agregando los campos


“IdEstado”, “Estado” y el id del país, como se muestra en la siguiente imagen.

Después insertamos datos en la tabla “Ciudad” rellenando los campos


“IdCiudad”, “Ciudad” e “IdEstado”. utilizando la instrucción
INSERT INTO Ciudad VALUES (‘Ci001’, ‘Oaxaca de Juarez’, ‘Es001’);

Luego seguimos Insertando datos en la tabla “Municipio” agregando datos


en los campos “idMunicipio”, “Municipio” y finalmente “idCiudad” para ello
se utilizo la instrucción INSERT INTO Municipio VALUES (‘Mu001’, ‘Zagoocho’
Ci001’); como se observa en la siguiente imagen.
Continuamos con insertando datos en la tabla “Tipo Asentamiento”
rellenando los campos “idTipoA” y “Asentamiento” utilizando la instrucción
INSERT INTO TipoAsentamiento VALUES (‘TA1’, ‘Colonia’); como se observa
en la siguiente imagen.

Después insertamos datos en la tabla “Código Postal” ingresando los datos


“IdCodigoP”, “CodigoP” Y finalmente “IdMunicipio”. Como se muestra en
la imagen.

Proseguimos insertando datos en la tabla “Asentamiento” la cual contine los


campos “IdAsentamiento”, “IdCodigoP” y finalmente “IdTipoA” todo esto se
inserto mediante la instrucción INSERT INTO Asentamiento VALUES (‘As001’,
‘CP0001’, ‘TA1’); como se observa en la siguiente imagen.
Proseguimos con la tabla “Calle” insertando los datos en los campos
“idCalle”, “NoCalle”, “Calle”, “idAsentamiento” ejecutando la instrucción
instrucción INSERT INTO Municipio VALUES (‘Mu001’, ‘Zagoocho’
Ci001’); como muestra en la imagen.

Siguiendo la sintaxis mencionada anteriormente realizamos la inserción de


todos los datos en las respectivas tablas “Dirección”, “Proveedor”, “Persona”,
“Cliente” , “Supervisor”, “Ticket”, “Compra”, “Detalle Compra” y por último
“Factura” obteniendo los resultados que se muestran en las imágenes.
ELIMINACIÓN
Para eliminar registros utilizamos la instrucción DELETE que permite
eliminar registros de una tabla, su sintaxis es simple, puesto que solo debemos
indicar que registros deseamos eliminar mediante la cláusula WHERE.

Para eliminar registros utilizamos la instrucción que se muestra a


continuación:

Delete from nombre de la tabla

Where nombre de la tabla = ‘Registro a eliminar’

Para ejemplificar realizamos la eliminación de la marca “Eagle Warrior”


correspondiente a la tabla “Marca”, ejecutando la instrucción que se
muestra en la imagen.
Al realizar una consulta se observa el registro de la marca “Eagle Warrior” y
al ejecutar la instrucción se elimino de la base de datos dicho registro

Posteriormente utilizamos la misma instrucción para eliminar el registro del


país Argentina .

Delete from Pais

Where Pais = ’Argentina’

En la siguiente imagen se observa que el país Argentina fue eliminado de la


tabla.
MODIFICACIÓN
La instrucción UPDATE permite actualizar registros de una tabla. Por lo tanto
se indica que registros se quiere actualizar mediante la cláusula WHERE, y
que campos mediante la cláusula SET, además se deberá indicar que nuevo
dato va a guardar cada campo. Para realizar el ejemplo se utilizó la
siguiente instrucción:

UPDATE nombre de la tabla


SET campo = nuevo valor
WHERE = valor a modificar

Realizamos la actualización de los datos de la tabla “Artículos” modificando


la cantidad de artículos que en este caso son “Mouse”.

En la imagen se puede observar en el campo cantidad con el número 10.


Posteriormente al ejecutar la instrucción se muestra el campo actualizado con el
nuero 15

Continuamos realizando actualizaciones de datos ahora en la tabla


persona, utilizando la instrucción que se muestra en la imagen, actualizando
los datos de los campos Nombre y el correo electrónico.

Se puede visualizar la actualización de los datos:


CONSULTAS
Finalmente realizamos consultas sobre los datos que almacenamos
anteriormente. Una consulta es la solicitud de información a una base de
datos y se realiza a través del comando SELECT, el cual permite seleccionar
las columnas que se van a mostrar y en el orden en que lo van a hacer.
Simplemente es la instrucción que la base de datos interpreta como que
vamos a solicitar información.

Iniciamos realizando una consulta a la tabla “Artículos” para comprobar los


datos existentes, utilizando la instrucción SELECT * FROM Articulos.

En la imagen de la consulta realizada muestra 2 registros de artículos, se


observa el Id el nombre del articulo su precio, la descripción, la cantidad, el
id de la marca y por último el id del modelo.
Continuamos solicitando la información de la tabla “Persona” a través de la
instrucción SELECT * FROM Perona.

Al realizar la consulta se pueden visualizar los datos de las personas que se


insertaron anteriormente, en la imagen se observan cuatro registros los
cuales contienen el id de la persona, su nombre, apellido paterno, apellido
materno, genero, el correo electrónico y por último el id dirección.

Continuamos realizando una consulta a la tabla “Persona” pero ahora


seleccionamos las columnas que se van a mostrar y el orden en que lo hará
para ello utilizamos la instrucción SELECT Nombre, apellidoP, apellidoM FROM
Persona.

En la imagen se observa que efectivamente se realizo la consulta y los datos


fueron mostrados como se indicó.
Posteriormente solicitamos los datos de la taba “Articulos” de igual manera
seleccionamos las columnas que se desean mostrar y el orden en que lo
hará, para ello ejecutamos la instrucción SELECT NombreArt, Cantidad, FROM
Articulos. En la imagen se observan los datos que solicitamos como son el
nombre del articulo y la cantidad, obteniendo el resultado deseado.

Por último ejecutamos todas las instrucciones para que se mostraran todas
las tabas que tenemos almacenadas.
Consulta con JOIN SIMPLE

Consulta con IN

Consulta con UNION


Consulta con INTERSECT

Consulta con DIFFERENCE

Consulta con Minus


TRANSACCIONES PLANAS Y/O ANIDADAS

Una transacción es una colección de acciones que hacen


transformaciones consistentes de los estados de un sistema preservando la
consistencia del sistema. Una base de datos está en un estado consistente
si obedece todas las restricciones de integridad definidas sobre ella.

En la siguiente actividad se diseñó e implemento el esquema de


transacciones planas y/o anidadas sobre nuestra base de datos.

Se inicio ejecutando una transacción en la tabla “Detalle ticket” para


aumentar los datos del campo cantidad, mediante la instrucción que se
muestra en la imagen, se realizaran cambios en el registro “Dt001” y “Dt002”.
Al ejecutar la instrucción se cumplió la transacción correctamente.

En la imagen se observan dos transacciones efectuadas, y el mensaje de


“Transacción completa”

Al realizar la consulta de la tabla ticket, con la instrucción SELECT *


FROM DetalleTicket; se observa que efectivamente se realizo el cambio en
el campo cantidad.
Posteriormente se realizó una transacción en la tabla “Artículos”, en este
caso se desarrollarán cambios al campo precio y al campo cantidad, con
la instrucción que se muestra en la imagen.

Al ejecutar la instrucción se obtuvieron resultados correctos, mostrando el mensaje


de “Transacción completa”
Finalmente se ejecutó una consulta para verificar los datos fueron
cambiados de forma correcta en la tabla “Artículos”, en la imagen se
observan resultados positivos.

Continuamos realizando una transacción en la tabla “DetalleTicket”


pero en este caso se realizará una “Transacción completa” y una
“Transacción cancelada”.
Al ejecutar la instrucción se observa que efectivamente se efectuó la
primer transacción pero la segunda no ya que nos muestra el mensaje
“Transacción cancelada”, porque la cantidad que se quiere restar es mayor
a la cantidad que se tiene registrada por lo tanto no es posible efectuar la
transacción.

PROCEDIMIENTOS ALMACENADOS
Un procedimiento almacenado es un conjunto de instrucciones de T-
SQL que SQL Server compila, en un único plan de ejecución, los llamados
"store procedures" se encuentran almacenados en la base de datos, los
cuales pueden ser ejecutados en cualquier momento.

proporcionan a los usuarios un acceso fácil a la base de datos, se


puede tener acceso a la base de datos sin tener que conocer los detalles
de la arquitectura de tablas -simplemente se ejecutan los procedimientos
almacenados que llevan a cabo las tareas solicitadas.

Se inicio creando el procedimiento con el nombre de “SP _ Sumar


Cantidad”, donde se definen las variables @IdDetalleTicket y @Cantidad,
el procedimiento se encarga de incrementar la columna de cantidad
dependiendo del id que se le ingrese.
En caso de que ya no sea necesaria la tabla esta se puede eliminar

Indicando con DROP PROCEDURE “SP_SumarCantidad” para ejecutar el


proceso.
Se Continua con la ejecución del procedimiento para sumarle 5 al artículo
Dt002, con la siguiente instrucción, indicando en la primera parte el
Identificador del artículo, seguido por la cantidad que se desea agregar.

Finalmente se efectuó una consulta a la tabla “Detalle ticket” y


efectivamente se realizaron los cambios correspondientes

Después realizamos un procedimiento almacenado a la tabla “Artículos”,


creando el procedimiento con la instrucción que se muestra en la imagen.
Posteriormente se ejecutó el procedimiento para sumar el precio a un
artículo, en este caso al artículo 2, aumentándole 1500 a ese artículo.

Se realizo una consulta a la tabla artículos con el comando SELECT * FROM


ARTICULOS; para verificar los cambios correspondientes.

ANTES de realizar el procedimiento el precio de la impresora era de 1800


DESPUÉS de ejecutar el procedimiento almacenado el campo precio de la
impresora cambio a 3300, se observa que el procedimiento se realizó con
éxito, como se muestra en la siguiente imagen:

Como último paso tenemos la creación de la agregación de una nueva


venta, con la siguiente secuencia de código se generó el procedimiento.
En caso de querer eliminar el procedimiento se realiza con el siguiente
código

Para agregar un nuevo registro de venta se realiza con el siguiente comando


SQL

Por último verificamos que se haya agregado el nuevo ticket, para esto se
hace con una consulta.
DISPARADORES
Un Trigger, también llamado Disparador, en una base de datos, es un
procedimiento que se ejecuta cuando se cumple una condición
establecida.
Depende de la base de datos, los Triggers pueden ser antes o después de
ejecutar un INSERT, UPDATE o DELETE.
Un Trigger funciona tanto al insertar, actualizar o borrar datos en una base
de datos o incluso al crear o editar usuarios. Son usados para mejorar la
administración de la Base de Datos, sin necesidad de que el usuario ejecute
esas sentencias SQL.

Se inicio creando una tabla llamada Historial_insert, definiendo las variables su


tipo y tamaño, donde se almacenarán los datos generados por una inserción
por cierto usuario, como se muestra en la siguiente imagen.

Posteriormente se creó nuestro disparador donde indicaremos que almacene


el id del artículo, también el nombre de la actividad que se realizó y que usuario
fue el que la realizo, como se observa en la imagen.
Se continúo insertando datos para el registro de un nuevo artículo, con la
instrucción que se observa en la imagen.

Después se verificó que se hayan agregado correctamente los datos del


registro en la tabla Historial_insert, y efectivamente se realizo de forma
correcta.

Trigger para guardar los datos de las ventas realizadas por los
supervisores

Primero se creó la tabla historial_Venta, definiendo las variables y sus


respectivos tipos y tamaños, para poder tener registradas las ventas echas
por los supervisores.

Posteriormente se creó nuestro disparador donde le asignamos que


almacene el id de la compra, también el nombre de la actividad que se
realizó y el usuario que lo realizo.
Después se realizó la prueba se insertando datos en una nueva compra,
con la instrucción que se muestra en la imagen.

Finalmente se verifico que se halla agregado correctamente el registro en la


tabla Historial_Venta

Trigger para guardar los datos de los registros de nuevas


personas

Se inicio creando la tabla historial_Paises para poder tener registradas las


ventas echas por los supervisores.

Después se creó nuestro disparador donde se le asignó que almacene el id


del país, también el nombre de la actividad que se realizó y el tipo de usuario
que la realizo.
Posteriormente se realizó la prueba agregando un nuevo país, con la
instrucción que se muestra en la imagen.

Finalmente se verifico que se halla agregado correctamente el registro en


la tabla Historial_Paises, obteniendo el resultado esperado.

Trigger para eliminar un país

Creamos nuestro disparador para donde se asignó que almacene el id del


país, también el nombre de la actividad que se realizó y por qué usuario fue
realizada.
Después ejecutamos el
comando DELETE FROM Pais, como
se muestra en la imagen.

Finalmente se realizó una consulta a la tabla de historial_paises, y


efectivamente en la imagen se muestra que se ejecutó con éxito.

Trigger para eliminar una persona

Iniciamos creando nuestro disparador donde se le asigno que almacene el


id de la persona, también el nombre de la actividad que se realizó y por qué
usuario fue realizada.
Posteriormente se ejecutó el comando DELETE FROM Persona, para eliminar
el nombre Juan de la tabla persona, como se muestra en la imagen.

Finalmente realizamos una consulta a la tabla de historial_Personas,


obteniendo resultados satisfactorios como se muestra en la imagen.

Trigger para eliminar un supervisor

Creamos nuestro disparador donde le diremos que almacene el id del


supervisor, también el nombre de la actividad que se realizó y por qué
usuario fue realizada.

Después ejecutamos el comando DELETE FROM Supervisor que se muestra


en la imagen.
Finalmente consultamos la tabla de historial_Supervisor, obteniendo
excelentes resultados.

CREACIÓN DE LOS INDICES


Para crear índices empleamos la instrucción "create index", utilizando la
sintaxis básica que se muestra a continuación:

create TIPODEINDICE index NOMBREINDICE on TABLA(CAMPO);

"TIPODEINDICE" indica si es agrupado (clustered) o no agrupado


(nonclustered). Si no especificamos crea uno No agrupado.
Independientemente de si es agrupado o no, también se puede especificar
que sea "unique", es decir, no haya valores repetidos. Si se intenta crear un
índice unique para un campo que tiene valores duplicados, SQL Server no
lo permite.
Para este ejemplo se creó un índice no agrupado para cada tabla,
utilizando la instrucción CREATE NONCLUSTERED INDEX, como se observa en
la imagen.
VISTAS

Mostrar datos de artículos no vendidos

Artículos que ya fueron vendidos


Mostrar datos de artículos vendidos

Eliminar vista de artículos vendidos

Eliminar vista de artículos no vendidos

USUARIOS Y ROLES
Creación de usuarios
Creación del segundo usuario

R E S P A L D O Y R E C U P E R A C I Ó N DE LA
BASEDEDATOS
Respaldo de la BD

Restaurar la BD
CREACION DE LA INTERFAZ DE LA BD
Para la creación de nuestra interfaz utilizamos Visual Studio, iniciamos
abrimos el proyecto en Visual Studio y, después, seleccionamos proyecto de
ahí Agregar nuevo origen de datos para iniciar el Asistente para la
configuración de orígenes de datos. De ahí seleccionamos la opción
Microsoft SQL Server.

De ahí seleccionamos la opción conjunto de base de datos.


Después seleccionamos nuestra de base de datos y de ahí guardamos la
conexión de la base de datos.

De ahí elegimos los objetos queremos que se importen a nuestro


entorno
De ahí solo arrastramos los campos que vallamos a necesitar para nuestra
interfaz.
En este caso los datos seleccionados fueron los de la persona.
CODIGO DEL PROYECTO EN SQL SERVER
/* Creación de la base de datos */
Create database Facturacion_tecnologicaas;
Go
Use Facturacion_tecnologicaas;
Go
/* Creación de las tablas */
DROP TABLE Persona;

CREATE TABLE Persona (


IdPersona VARCHAR(6) PRIMARY KEY NOT NULL,
Nombre VARCHAR(15) NOT NULL,
ApellidoP VARCHAR(15),
ApellidoM VARCHAR(15),
Genero CHAR(1) CHECK(Genero='H' or Genero='M'),
Correo VARCHAR(30),
IdDireccion VARCHAR(5) REFERENCES Direccion NOT NULL
);
CREATE TABLE Supervisor (
IdSupervisor VARCHAR(2) NOT NULL PRIMARY KEY,
IdPersona VARCHAR(6) REFERENCES Persona NOT NULL
);

DROP TABLE Cliente;

Create table Cliente (


IdCliente VARCHAR(5) NOT NULL PRIMARY KEY,
IdPersona VARCHAR(6) REFERENCES Persona NOT NULL
);

DROP TABLE Direccion;

Create table Direccion (


IdDireccion VarChar(5) not null Primary key,
IdCalle VarChar(5) references Calle not null
);

DROP TABLE Calle;


Create table Calle (
IdCalle VarChar(5) not null Primary key,
NoCalle int not null,
Calle VarChar(50) not null,
IdAsentamiento VarChar(5) references Asentamiento not null
);

DROP TABLE Asentamiento;

Create table Asentamiento (


IdAsentamiento VarChar(5) not null Primary key,
IdCodigoP VarChar(7) references CodigoPostal not null,
IdTipoA VarChar(3) references TipoAsentamiento not null
);

DROP TABLE TipoAsentamiento;

Create table TipoAsentamiento (


IdTipoA VarChar(3) not null Primary key,
Tipo VarChar(20) not null
);

DROP TABLE CodigoPostal;

Create table CodigoPostal (


IdCodigoP VarChar(7) not null Primary Key,
CodigoP int unique not null,
IdMunicipio VarChar(5) references Municipio not null
);

DROP TABLE Municipio;

Create table Municipio (


IdMunicipio VarChar(5) not null Primary key,
Municipio VarChar(50) unique not null,
IdCiudad VarChar(5) references Ciudad not null
);

DROP TABLE Ciudad;


Create table Ciudad (
IdCiudad VarChar(5) not null Primary key,
Ciudad VarChar(50) unique not null,
IdEstado VarChar(5) references Estado not null
);

DROP TABLE Estado;

Create table Estado (


IdEstado VarChar(5) not null Primary key,
Estado VarChar(30) unique not null,
IdPais VarChar(5) references Pais not null
);

DROP TABLE Pais;

Create table Pais (


IdPais VarChar(5) not null Primary key,
Pais VarChar(60) unique not null
);

DROP TABLE Modelo;

Create table Modelo (


IdModelo VarChar(5) not null Primary key,
Modelo VarChar(20) unique not null
);
DROP TABLE Marca;

Create table Marca (


IdMarca VarChar(5) not null Primary key,
Marca VarChar(20) unique not null
);

DROP TABLE DetalleTicket;

Create table DetalleTicket (


IdDetalleTicket VarChar(5) not null Primary key,
IdTicket VarChar(5) references Ticket not null,
IdArticulo VarChar(6) references Articulos not null,
Cantidad int check (Cantidad > 0) not null,
PrecioVenta Float(6) check (PrecioVenta > 0) not null
);
DROP TABLE Ticket;

Create table Ticket (


IdTicket VarChar(5) not null Primary key,
FechaVenta Datetime default(getdate()) not null,
Iva Float(3) not null,
IdCliente VarChar(5) references Cliente not null,
IdSupervisor VarChar(2) references Supervisor not null
);

DROP TABLE DetalleCompra;

Create table DetalleCompra (


IdDetalleC VarChar(5) not null Primary key,
IdCompra VarChar(5) references Compra not null,
IdArticulo VarChar(6) references Articulos not null,
Cantidad int check (Cantidad > 0) not null,
PrecioCompra float(5) check (PrecioCompra > 0) not null
);

DROP TABLE Compra;

Create table Compra (


IdCompra VarChar(5) not null Primary key,
FechaCompra date not null,
IdProveedor VarChar(5) references Proveedor not null,
IdSupervisor VarChar(2) references Supervisor not null
);

DROP TABLE Proveedor;

Create table Proveedor (


IdProveedor VarChar(5) not null primary key,
Nombre Varchar(20) not null,
TelefonoProv Varchar(15) not null,
IdArticulo VarChar(6) references Articulos not null,
CorreoElectronicoP VarChar(40) not null,
IdDireccion VarChar(5) references Direccion not null
);

DROP TABLE Articulos;

Create table Articulos (


IdArticulo VarChar(6) not null Primary key,
NombreArt VarChar(60) not null,
Precio int check (Precio > 0) not null,
Descripcion VarChar(200) not null,
Cantidad int CHECK (Cantidad > 0) not null,
IdMarca VarChar(5) references Marca not null,
IdModelo VarChar(5) references Modelo not null
);

DROP TABLE Factura;

Create table Factura (


IdFactura Varchar(8) not null Primary key,
FechaFactura Datetime not null,
IdCliente Varchar(5) references Cliente not null,
IdTicket Varchar(5) references Ticket not null
);

/* I n s e r t */

INSERT INTO Marca VALUES('Ma001','Vorago');

INSERT INTO Marca VALUES('Ma002','Canon');

INSERT INTO Marca VALUES ('Ma003', 'HP');

INSERT INTO Marca VALUES ('Ma004', 'Acer');

INSERT INTO Marca VALUES ( 'Ma005','Eagle Warrior');

INSERT INTO Modelo VALUES('Mo001','Mm303');

INSERT INTO Modelo VALUES('Mo002','MG102');


INSERT INTO Articulos VALUES('Art001','Mouse',250,'Inalámbrico con
leds',10,'Ma001','Mo001');

INSERT INTO Articulos VALUES('Art002','Impresora MG102',1800,'Impresiones de


calidad Blanco,Negro y Color',5,'Ma002','Mo002');

INSERT INTO Pais VALUES('Pa001','México');

INSERT INTO Pais VALUES('Pa002','EUA');

INSERT INTO Pais VALUES('Pa003','Argentina');

INSERT INTO Estado VALUES('Es001','Oaxaca','Pa001');

INSERT INTO Estado VALUES('Es002','San Luis Potosi','Pa001');

INSERT INTO Estado VALUES('Es003','Sonora','Pa001');

INSERT INTO Ciudad VALUES('Ci001','Oaxaca de Juarez','Es001');

INSERT INTO Ciudad VALUES('Ci002','San Luis Potosi','Es002');

INSERT INTO Ciudad VALUES('Ci003','Hermosillo','Es003');

INSERT INTO Municipio VALUES('Mu001','Zogoocho','Ci001');

INSERT INTO Municipio VALUES('Mu002','San Francisco Javier Xoxocotlán','Ci001');

INSERT INTO Municipio VALUES('Mu003','San Jose Hidalgo Atzompa','Ci001');

INSERT INTO TipoAsentamiento VALUES('TA1','Colonia');

INSERT INTO TipoAsentamiento VALUES('TA2','Fraccionamiento');

INSERT INTO CodigoPostal VALUES('CP00001',71234,'Mu001');

INSERT INTO CodigoPostal VALUES('CP00002',71246,'Mu002');

INSERT INTO CodigoPostal VALUES('CP00003',71238,'Mu003');


INSERT INTO Asentamiento VALUES('As001','CP00001','TA1');

INSERT INTO Asentamiento VALUES('As002','CP00002','TA2');

INSERT INTO Asentamiento VALUES('As003','CP00003','TA1');

INSERT INTO Calle VALUES('Ca001',1,'Bugambilias','As001');

INSERT INTO Calle VALUES('Ca002',12,'Insurgentes','As002');

INSERT INTO Calle VALUES('Ca003',136,'Independencia','As003');

INSERT INTO Direccion VALUES('Di001','Ca001');

INSERT INTO Direccion VALUES('Di002','Ca002');

INSERT INTO Direccion VALUES('Di003','Ca003');

INSERT INTO Proveedor


VALUES('Pr001','Jorge','9515923048','Art001','[email protected]','Di003');

INSERT INTO Proveedor


VALUES('Pr002','Reynaldo','9513339090','Art002','[email protected]','Di003');

INSERT INTO Persona


VALUES('P00001','Juan','Perez','Perez','H','[email protected]','Di002');

INSERT INTO Persona


VALUES('P00002','Uriel','Martinez','Lopez','H','[email protected]','Di003');

INSERT INTO Persona


VALUES('P00003','Mateo','Juarez','Juarez','H','[email protected]','Di001');

INSERT INTO Persona


VALUES('P00004','Maria','Sirvana','Jimenez','M','[email protected]','Di002');

INSERT INTO Cliente VALUES('Cl001','P00004');

INSERT INTO Cliente VALUES('Cl002','P00001');


INSERT INTO Cliente VALUES('Cl003','P00003');

INSERT INTO Supervisor VALUES('S1','P00002');

INSERT INTO Ticket VALUES('Ti001','2021-02-18',0.16,'Cl001','S1');

INSERT INTO Ticket VALUES('Ti002','2021-02-19',0.16,'Cl002','S1');

INSERT INTO Ticket VALUES('Ti003','2021-02-19',0.16,'Cl003','S1');

INSERT INTO Compra VALUES('Co001','2021-01-10','Pr001','S1');

INSERT INTO Compra VALUES('Co002','2021-01-10','Pr002','S1');

INSERT INTO DetalleCompra VALUES('Dc001','Co001','Art001',10,2500);

INSERT INTO DetalleCompra VALUES('Dc002','Co001','Art002',5,9000);

INSERT INTO DetalleTicket VALUES('Dt001','Ti001','Art001',3,750);

INSERT INTO DetalleTicket VALUES('Dt002','Ti002','Art002',1,1800);

INSERT INTO DetalleTicket VALUES('Dt003','Ti003','Art001',1,250);

INSERT INTO Factura VALUES('FA000001','2021-06-09','Cl001','Ti001');

INSERT INTO Factura VALUES('FA000002','2021-06-10 12:56:35.675','Cl002','Ti002');


/*U p d a t e*/

Update Marca
set Marca ='Eagle Warrior'
where Marca = 'Eagle'

Update Articulos
set Cantidad = 15
where Cantidad = 10

Update Persona
set Nombre = 'Axel',correo= '[email protected]'
where Nombre = 'Juan'
/* D e l e t e*/

Delete from Marca


where Marca ='Eagle Warrior’'

Delete from Pais


where Pais ='Argentina'
/* Consultas a las tablas de la base de datos */

SELECT * FROM Articulos;

SELECT * FROM Ticket;

SELECT * FROM DetalleTicket;

SELECT * FROM Pais;

SELECT * FROM Estado;

SELECT * FROM Ciudad;

SELECT * FROM Municipio;

SELECT * FROM TipoAsentamiento;

SELECT * FROM Direccion;

SELECT * FROM CodigoPostal;

SELECT * FROM Calle;

SELECT * FROM Proveedor;

SELECT * FROM Cliente;

SELECT * FROM Persona;

SELECT * FROM Supervisor;

SELECT * FROM Compra;

SELECT * FROM Factura;


SELECT * FROM Asentamiento;

SELECT * FROM Marca;

SELECT * FROM Modelo;

SELECT Nombre, apellidoP, apellidoM from Persona;

SELECT NombreArt, Cantidad from Articulos;

/* Consulta con JOIN SIMPLE */

SELECT art.IdArticulo, art.NombreArt, dt.Cantidad, dt.PrecioVenta


FROM Articulos art
INNER JOIN DetalleTicket dt ON dt.IdArticulo=art.IdArticulo

/* Consulta con IN */

SELECT Nombre, TelefonoProv, CorreoElectronicoP


FROM Proveedor
WHERE Nombre IN ('Jorge','Reynaldo');

/* Consulta con UNION */


/* Primera union */
SELECT IdMarca, Marca FROM Marca
UNION
SELECT IdModelo, Modelo FROM Modelo;
/* Segunda union */
SELECT Nombre, TelefonoProv, CorreoElectronicoP FROM Proveedor
UNION
SELECT Nombre, ApellidoP, ApellidoM FROM Persona
/* Consulta con INTERSECT */

SELECT IdMarca, Marca [Modelo]


FROM Marca [Modelo]
INTERSECT
SELECT IdMarca, Marca [Modelo]
FROM Marca [Modelo]
/* Consulta con DIFFERENCE */

SELECT DIFFERENCE('Acer','Jorge');

SELECT DIFFERENCE('Teclado','Mouse');
SELECT DIFFERENCE('Jorge','Juan');

SELECT DIFFERENCE('Bugambilias','Insurgentes');

SELECT DIFFERENCE('Dt002','Dt003');
/* Consulta con Minus */

SELECT FechaCompra FROM Compra


MINUS
SELECT FechaVenta FROM Ticket

/* V I S T A S */

/* Mostrar los datos de los articulos que se han vendido */


SELECT DISTINCT IdArticulo, NombreArt, Marca, Modelo
FROM Articulos, Marca, Modelo
WHERE EXISTS
(SELECT * FROM DetalleTicket
WHERE Articulos.IdArticulo=DetalleTicket.IdArticulo)
AND Articulos.IdMarca=Marca.IdMarca
AND Articulos.IdModelo=Modelo.IdModelo

/* Mostrar los datos de los articulos que no se han vendido */


SELECT DISTINCT IdArticulo, NombreArt, Marca, Modelo
FROM Articulos, Marca, Modelo
WHERE NOT EXISTS
(SELECT * FROM DetalleTicket
WHERE Articulos.IdArticulo=DetalleTicket.IdArticulo)
AND Articulos.IdMarca=Marca.IdMarca
AND Articulos.IdModelo=Modelo.IdModelo

/* Crear una vista de los productos que ya se han vendido */


GO

CREATE VIEW V_Vendidos


AS SELECT DISTINCT IdArticulo, NombreArt, Marca, Modelo
FROM Articulos, Marca, Modelo
WHERE EXISTS
(SELECT * FROM DetalleTicket
WHERE Articulos.IdArticulo=DetalleTicket.IdArticulo
AND Articulos.IdMarca=Marca.IdMarca
AND Articulos.IdModelo=Modelo.IdModelo);

GO
/*Mostrar la vista de los productos vendidos */

SELECT DISTINCT IdArticulo, NombreArt, Marca, Modelo


FROM V_Vendidos
ORDER BY NombreArt;

/* Eliminar la vista de los productos vendidos */

DROP VIEW V_Vendidos;

/* Crear una vista de los productos que no han sido vendidos */


GO

CREATE VIEW V_NoVendidos


AS SELECT DISTINCT IdArticulo, NombreArt, Marca, Modelo
FROM Articulos, Marca, Modelo
WHERE NOT EXISTS
(SELECT * FROM DetalleTicket
WHERE Articulos.IdArticulo=DetalleTicket.IdArticulo)
AND Articulos.IdMarca=Marca.IdMarca
AND Articulos.IdModelo=Modelo.IdModelo;

GO
/* Mostrar la vista de los productos no vendidos */

SELECT DISTINCT IdArticulo, NombreArt,Marca,Modelo


FROM V_NoVendidos
ORDER BY NombreArt;

/* Eliminar la vista de no vendidos */

DROP VIEW V_NoVendidos;

/* U S U A R I O S Y R O L E S */

/* Creación de usuarios y roles */


CREATE LOGIN Supervisor WITH PASSWORD='Contrasena12345';

USE Facturacion_tecnologica;

CREATE USER Supervisor FOR LOGIN Supervisor;

ALTER ROLE db_datareader ADD member Supervisor;

/* Creación del usuario Brenda en la base de datos */

CREATE LOGIN Brenda WITH PASSWORD='Brenda12345';

USE Facturacion_tecnologias;

CREATE USER Brenda FOR LOGIN Brenda;

ALTER ROLE db_denydatareader ADD member Brenda;

/* R E S P A L D O Y R E C U P E R A C I Ó N DE LA B A S E D E D A T O S */

/* Respaldar la base de datos */

BACKUP DATABASE [Facturacion_tecnologica]


TO DISK = N'/var/opt/mssql/data/Facturacion_tecnologica-2021620-6-45-36.bak'
WITH NOFORMAT, NOINIT, NAME =N'Facturacion_tecnologica_backup', SKIP,
NOREWIND, NOUNLOAD, COMPRESSION,
STATS = 10
GO

/* Restaurar la base de datos */

USE [master]
RESTORE DATABASE [Facturacion_tecnologica]
FROM DISK = N'/var/opt/mssql/data/Facturacion_tecnologica-2021620-6-45-
36.bak'
WITH FILE = 1, NOUNLOAD, STATS = 5
GO
/*t r a n s a c c i o n e s*/

/*Iniciar y deshacer transacciones*/


BEGIN transaction
DELETE FROM Articulos
where IdArticulo = 1
ROLLBACK

/*Iniciar y confirmar transacciones*/

BEGIN transaction
DELETE FROM Marca, Articulos, Modelo
Where IdMarca= 'Ma001'
COMMIT

BEGIN TRY
BEGIN TRANSACTION
UPDATE DetalleTicket SET Cantidad = Cantidad + 3 WHERE IdDetalleTicket=
'Dt001'
UPDATE DetalleTicket SET Cantidad = Cantidad -2 WHERE IdDetalleTicket=
'Dt002'
COMMIT TRANSACTION
PRINT 'Transaccion completa'
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION
PRINT 'Transaccion cancelada'
END CATCH

/*Segunda transacción*/
BEGIN TRY
BEGIN TRANSACTION
UPDATE Articulos SET Precio = Precio + 50 WHERE IdArticulo= 'Art001'
UPDATE Articulos SET Cantidad = Cantidad +10 WHERE IdArticulo= 'Art002'
COMMIT TRANSACTION
PRINT 'Transaccion completa'
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION
PRINT 'Transaccion cancelada'
END CATCH
/*Transaccion cancelada*/
BEGIN TRY
BEGIN TRANSACTION
UPDATE DetalleTicket SET PrecioVenta = PrecioVenta + 30 WHERE
IdDetalleTicket= 'Dt001'
UPDATE DetalleTicket SET PrecioVenta = PrecioVenta -300 WHERE
IdDetalleTicket= 'Dt003'
COMMIT TRANSACTION
PRINT 'Transaccion completa'
END TRY
BEGIN CATCH
ROLLBACK TRANSACTION
PRINT 'Transaccion cancelada'
END CATCH
GO
/* P R O C E D I M I E N T O S*/
CREATE PROCEDURE SP_SumarCantidad

@IdDetalleTicket as Varchar(5),
@Cantidad as int
AS
UPDATE DetalleTicket
SET Cantidad=Cantidad+@Cantidad
WHERE IdDetalleTicket=@IdDetalleTicket
GO
EXEC SP_SumarCantidad 'Dt002', 5
/* Eliminar el procedimiento */
DROP PROCEDURE SP_SumarCantidad
/*Segundo procedimiento*/
GO
CREATE PROCEDURE SP_SumarPrecio

@IdArticulo as Varchar(6),
@Precio as int
AS
UPDATE Articulos
SET Precio=Precio+@Precio
WHERE IdArticulo=@IdArticulo

EXEC SP_SumarPrecio'Art002', 1500


DROP PROCEDURE SP_SumarCantidad

SELECT * FROM Articulos;

/* Procedimiento para agregar una venta */


GO
CREATE PROCEDURE SP_AgregarVenta
@IdDetalleTicket VARCHAR(5),
@IdTicket VARCHAR(5),
@Cantidad int,
@IdArticulo VARCHAR(6)
AS
BEGIN
SET NOCOUNT ON
SET XACT_ABORT ON
BEGIN TRY
BEGIN TRANSACTION
DECLARE @PV INT
SELECT @PV = Precio FROM Articulos WHERE Articulos.IdArticulo=@IdArticulo
INSERT INTO DetalleTicket(IdDetalleTicket,IdTicket,IdArticulo, Cantidad,
PrecioVenta)
VALUES(@IdDetalleTicket,@IdTicket, @IdArticulo, @Cantidad, @PV)

UPDATE Articulos
SET Cantidad = Cantidad - @Cantidad
WHERE IdArticulo = @IdArticulo
AND Cantidad = @Cantidad
SET NOCOUNT OFF;
COMMIT TRANSACTION
END TRY
BEGIN CATCH
SELECT ERROR_MESSAGE()
PRINT 'CATCH'
IF @@TRANCOUNT>0
ROLLBACK
END CATCH
END
GO
EXEC SP_AgregarVenta 'Dt005','Ti002', 12, 'Art002';

SELECT @@TRANCOUNT AS Trancount


/*Eliminar el procedimiento de agregarVenta */

DROP PROCEDURE SP_AgregarVenta

/* D I S PA R A D O R E S*/
GO
CREATE TRIGGER Tr_pais
on Pais for insert
AS
set nocount on--muestra los mensejes en una fila afectada
declare @IdPais varchar(5)
select @IdPais = IdPais from inserted
insert into Historial_Paises values(GETDATE(),@IdPais,'Pais agregado',SYSTEM_USER)
go
CREATE TRIGGER TR_EliminarPais
on Pais instead of delete
as
begin
set nocount on;
insert into Historial_Paises(Fecha,IdPais,Accion,Usuario)
Select GETDATE(),IdPais,'Elimino un pais',SYSTEM_USER
from deleted
end
DELETE FROM Persona
GO

CREATE TRIGGER TR_EliminarPersonas


on Persona instead of delete
as
begin
set nocount on;
insert into Historial_Personas(Fecha,IdPersona,Accion,Usuario)
Select GETDATE(),IdPersona,'Persona eliminada',SYSTEM_USER
from deleted
end
select * from Historial_Personas
select * from Persona
select * from Historial_Paises
select * from Pais
GO
CREATE TRIGGER TR_EliminarSupervisores
on Supervisor instead of delete
as
begin
set nocount on;
insert into Historial_Supervisor(Fecha,IdSupervisor,Accion,Usuario)
Select GETDATE(),IdSupervisor,'Supervisor eliminado',SYSTEM_USER
from deleted
end
CREATE TABLE Historial_Paises
(Fecha datetime,
IdPais Varchar(6),
Accion varchar(80),
Usuario varchar(80));
/* Creación de los indices */
CREATE NONCLUSTERED INDEX IDX_Pais
ON Pais(Pais);

CREATE NONCLUSTERED INDEX IDX_Estado


ON Estado(Estado);

CREATE NONCLUSTERED INDEX IDX_Ciudad


ON Ciudad(Ciudad);

CREATE NONCLUSTERED INDEX IDX_Municipio


ON Municipio(Municipio);

CREATE NONCLUSTERED INDEX IDX_CP


ON CodigoPostal(CodigoP);

CREATE NONCLUSTERED INDEX IDX_Calle


ON Calle(Calle);

CREATE NONCLUSTERED INDEX IDX_Persona


ON Persona(Nombre,ApellidoP,ApellidoM);

CREATE NONCLUSTERED INDEX IDX_Marca


ON Marca(Marca);

CREATE NONCLUSTERED INDEX IDX_Modelo


ON Modelo(Modelo);

CREATE NONCLUSTERED INDEX IDX_Compra


ON Compra(FechaCompra);

CREATE NONCLUSTERED INDEX IDX_DetalleCompra


ON DetalleCompra(Cantidad,PrecioCompra);

/* Consulta elaborada */

SELECT Nombre, ApellidoP, ApellidoM,Marca, Modelo, DetalleTicket.Cantidad,


PrecioVenta, Nombre, ApellidoP, ApellidoM
FROM Articulos, DetalleTicket, Ticket, Marca, Modelo, Cliente , Persona,
Supervisor,Factura
WHERE Articulos.IdMarca=Marca.IdMarca
AND Articulos.IdModelo=Modelo.IdModelo
AND Articulos.IdArticulo=DetalleTicket.IdArticulo
AND Ticket.IdCliente=Cliente.IdCliente
AND Ticket.IdTicket=Factura.IdTicket
AND DetalleTicket.IdTicket=Ticket.IdTicket
AND Factura.IdCliente=Cliente.IdCliente
AND Persona.IdPersona=Supervisor.IdPersona
AND Persona.IdPersona=Cliente.IdPersona
CONCLUSIÓN

Podemos concluir en nuestra bitácora, que a lo largo de este


proyecto nos encontramos con varios sectores durante diversos ejemplos, lo
que nos llevo a poder comprender desde varias maneras de registrar,
eliminar, modificar y consultar registros en tablas de bases de datos de tal
manera que se identificaran las llaves primarias y foráneas que habitaban
en nuestro proyecto logrando así relaciones entra todas las tablas
generadas, todo esto nos ayudara a aportar mucho en nuestro perfil como
informáticos tanto en la escuela como en un futuro al estar en un entorno
laboral, de igual manera nos familiarizamos con disparadores para obtener
mayor seguridad e integridad de la información por lo que estos
disparadores o bien conocidos como triggers establecen algunas
restricciones dentro de la base de datos, también pudimos establecer roles
de usuarios dentro de la base de datos para así generar un mejor control
dentro de la base de datos, por ultimo logramos generar una conexión entre
la base de datos con un entorno ya gráficamente haciendo conexión través
de la herramienta de Visual Studio Code, mostrando así nuestros registros
almacenados de una mejor manera y más ágil al momento de querer
visualizarlos.

También podría gustarte