Modulo 4
Modulo 4
Introducción
En el módulo 4 veremos conceptos avanzados de SQL, como los procedimientos almacenados,
funciones, SQL dinámico y múltiples ejemplos relacionados. Aprenderemos cómo crear un
disparador, qué son los cursores y cómo manejar errores. Por último, aprenderemos qué es una
base de datos NoSQL, los tipos existentes y algunos ejemplos con MongoDB. A modo de cierre,
presentaremos una comparativa entre bases SQL y NoSQL.
Mejorando nuestro proyecto
Video de inmersión
Los procedimientos almacenados pueden realizar tanto el procesamiento de datos como la lógica
de aplicación dentro de la misma base de datos. Por ejemplo, un procedimiento almacenado
podría implementar la lógica para aceptar una orden del cliente o para transferir dinero de una
cuenta bancaria a otra.
Funciones
Las funciones son programas SQL almacenados que devuelven un solo valor para cada fila de
datos. A diferencia de los procedimientos almacenados, las funciones se invocan a través de
sentencias SQL en casi cualquier cláusula en la que se pueda utilizar un nombre de columna.
Esto las hace ideales para realizar cálculos y transformaciones de datos en los datos que se
muestran en los resultados de la consulta o utilizados en las condiciones de búsqueda. Casi
todos los productos DBMS relacionales vienen con un conjunto de funciones suministradas por el
proveedor para uso general y, por lo tanto, las funciones añadidas por los usuarios de la base de
datos local a menudo se denominan “funciones definidas por el usuario”.
Procedimientos almacenados
Con procedimientos almacenados, el lenguaje SQL se amplía en varias capacidades
normalmente asociadas con lenguajes de programación. Las secuencias de sentencias SQL se
agrupan para formar programas o procedimientos SQL. Tanto para los procedimientos como para
las funciones se utiliza una extensión de SQL denominada PL/SQL.
Ejecución condicional: una estructura IF... THEN ... ELSE permite un uso de un
procedimiento SQL para probar una condición y llevar a cabo diferentes operaciones
dependiendo del resultado.
Bucle: un ciclo WHILE o FOR o una estructura similar permiten realizar una secuencia de
operaciones SQL repetidamente hasta que se cumpla alguna condición de terminación.
Algunas implementaciones proporcionan una estructura de bucle especial con base en
cursor para procesar cada fila de resultados de consulta.
Estructura de bloques: una secuencia de sentencias SQL puede agruparse en un solo
bloque y utilizarse en otras construcciones de flujo de control como si el bloque de
instrucciones fuera una sola sentencia.
Variables nombradas: un procedimiento SQL puede almacenar un valor que ha calculado,
recuperado de la base de datos o derivado de alguna otra forma en una variable de
programa, y recuperar posteriormente el valor almacenado para su uso en cálculos
subsiguientes.
Procedimientos con nombre: una secuencia de sentencias SQL puede agruparse, asignar
un nombre y asignar parámetros formales de entrada y salida, como una subrutina o una
función en un lenguaje de programación convencional. Una vez definido de esta manera, el
procedimiento puede ser llamado por nombre y pasar los valores apropiados para sus
parámetros de entrada. Si el procedimiento es una función que devuelve un valor, puede
utilizarse en expresiones de valor de SQL.
Consideremos el proceso de agregar un cliente a la base de datos. Los pasos que pueden estar
involucrados son los siguientes:
Obtener el número de cliente, nombre, límite de crédito y cantidad de ventas objetivo para el
cliente, así como el vendedor y la oficina asignados.
Agregar una fila a la tabla de cliente que contiene los datos del cliente.
Actualizar la fila del vendedor asignado, aumentando el objetivo de cuota en la cantidad
especificada.
Actualizar la fila de la oficina, aumentando la meta de ventas en la cantidad especificada.
Confirmar los cambios en la base de datos, si todas las declaraciones anteriores tuvieron
éxito.
Sin una capacidad de procedimiento almacenado, hay una secuencia de instrucciones SQL que
hace este trabajo para XYZ Corporation, el nuevo número de cliente 2137, con un límite de
crédito de $ 30 000 y ventas de $ 50 000 para asignar a Paul Cruz (empleado N.° 103) de la
oficina de Chicago:
UPDATE SALESREPS SET QUOTA = QUOTA + 50000.00 WHERE EMPL_NUM = 103; UPDATE
OFFICES SET TARGET = TARGET + 50000.00 WHERE CITY = 'Chicago'; COMMIT;
Con un procedimiento almacenado, todo este trabajo se puede integrar en una única rutina SQL
definida.
nombre
Integer,
As
new_cuota number(16,2);
Variables
new_target number(16,2);
Begin
Credit_Limit)
Values
Update Salesreps
Update Offices
Commit;
End; Fin
Parámetros
Entrada [IN].
Salida [OUT].
Entrada-salida [IN-OUT].
Los nombres de los parámetros pueden aparecer dentro del cuerpo del procedimiento,
dondequiera que pueda aparecer una constante. Cuando aparece un nombre de parámetro, el
DBMS utiliza su valor actual.
Además de los parámetros de entrada, algunos lenguajes SPL también admiten parámetros de
salida. Esto permite que un procedimiento almacenado devuelva valores que calcula durante su
ejecución. Los parámetros de salida proporcionan una capacidad importante para pasar
información de un procedimiento almacenado a otro procedimiento almacenado que lo llama, y
también puede ser útil para depurar procedimientos almacenados utilizando SQL interactivo.
Algunos lenguajes SPL admiten parámetros que funcionan como parámetros de entrada y salida.
En este caso, el parámetro pasa un valor al procedimiento almacenado y cualquier cambio en el
valor durante la ejecución del procedimiento se refleja en el procedimiento de llamada.
Variables
Se declaran al principio del cuerpo del procedimiento, justo después del encabezado del
procedimiento y antes de la lista de sentencias SQL. Los tipos de datos de las variables pueden
ser cualquiera de los tipos de datos SQL soportados como tipos de datos de columna por el
DBMS.
Las variables locales dentro de un procedimiento almacenado pueden utilizarse como fuente de
datos dentro de las expresiones SQL en cualquier lugar en que pueda aparecer una constante. El
valor actual de la variable se utiliza en la ejecución de la sentencia. Además, las variables locales
pueden ser destinos para datos derivados de expresiones o consultas SQL.
Una vez definido por la instrucción CREATE PROCEDURE, el procedimiento se puede utilizar. Un
programa de aplicación puede solicitar la ejecución del procedimiento almacenado si utiliza la
instrucción SQL adecuada. Otro procedimiento almacenado puede llamar para realizar una
función específica. El procedimiento almacenado también se puede invocar a través de una
interfaz interactiva de SQL.
El programa llama al procedimiento almacenado y le pasa los seis valores especificados como
sus parámetros. El DBMS ejecuta el procedimiento almacenado y lleva a cabo cada sentencia
SQL en la definición del procedimiento, una por una. Si el procedimiento ADD_CUST completa
su ejecución con éxito, se ha llevado a cabo una transacción confirmada dentro del DBMS. Si
esto no ocurre, el código de error devuelto y el mensaje indican qué fue lo que falló.
Los valores que se deben utilizar para los
50000.00, 103,'Chicago');
30000.00, c_offc = 'Chicago', c_rep = 103, caso los valores de parámetro se pueden
Funciones
Además de los procedimientos almacenados, la mayoría de los lenguajes SPL soporta funciones
almacenadas. La diferencia es que una función devuelve una sola cosa (como un valor de datos,
un objeto o un documento XML) cada vez que se invoca, mientras que un procedimiento
almacenado puede devolver muchas cosas o nada. El soporte para los valores devueltos varía
según el lenguaje SPL. Las funciones se utilizan comúnmente como expresiones de columna en
sentencias SELECT y, por lo tanto, se invocan una vez por fila en el conjunto de resultados. Esto
permite que la función realice cálculos, conversión de datos y otros procesos para producir el
valor devuelto para la columna. A continuación, se muestra un ejemplo sencillo de una función
almacenada.
/* Return total order amount for a customer */ create function get_tot_ords(c_num in number)
return number
as
begin
from orders
end;
A medida que el DBMS evalúa la condición de búsqueda para cada fila de resultados de la
consulta, utiliza el número de cliente de la fila candidata actual (CUST_NUM) como un argumento
a la función GET_TOT_ ORDS y comprueba si supera el umbral de $ 10 000. Esta misma
consulta podría expresarse como una consulta agrupada, con la tabla ORDERS también incluida
en la cláusula FROM y los resultados agrupados por el cliente y el vendedor. En muchas
implementaciones, el DBMS lleva a cabo la consulta agrupada más eficientemente que la
precedente, lo que probablemente obliga al DBMS a procesar la tabla de pedidos una vez para
cada cliente.
1. El programa construye una sentencia SQL como una cadena de texto en una de sus áreas
de datos y la almacena en la memoria como una variable con nombre. La sentencia puede
ser casi cualquier sentencia SQL que no recupera datos.
2. El programa pasa la instrucción SQL al DBMS con la instrucción EXECUTE IMMEDIATE.
3. El DBMS ejecuta la sentencia y establece los valores SQLCODE / SQLSTATE para indicar
el estado de finalización, exactamente como si la sentencia hubiera sido codificada
mediante SQL estático.
La instrucción EXECUTE IMMEDIATE es la forma más simple de SQL dinámico, pero es muy
versátil. Podemos utilizarla para ejecutar dinámicamente la mayoría de las sentencias DML,
incluidas INSERT, DELETE, UPDATE, COMMIT y ROLLBACK. También podemos utilizar
EXECUTE IMMEDIATE para ejecutar dinámicamente la mayoría de las sentencias DDL, incluidas
las instrucciones CREATE, DROP, GRANT y REVOKE.
Sin embargo, la instrucción EXECUTE IMMEDIATE tiene una limitación significativa: no podemos
utilizarla para ejecutar dinámicamente una sentencia SELECT, ya que no proporciona un
mecanismo para procesar los resultados de la consulta. Así como SQL estático requiere cursores
y declaraciones de propósito especial (DECLARE CURSOR, OPEN, FETCH y CLOSE) para
consultas programáticas, SQL dinámico utiliza cursores y algunas nuevas instrucciones de
propósito especial para manejar consultas dinámicas.
Es importante advertir que la entrada del usuario no debe colocarse directamente en sentencias
SQL (como se muestra en los ejemplos simplificados anteriores) sin analizarlas primero. Hacerlo
le permitiría a un hacker incluir caracteres en la entrada, que terminaría la sentencia SQL
deseada y añadiría otra al final de ella, lo cual permitiría el acceso no autorizado a otros datos en
la base de datos, una técnica conocida como “inyección de SQL”.
Ejecutemos una consulta para recuperar el importe de la orden, el nombre del cliente y el
nombre del vendedor para cada pedido.
Para cada fila de resultados de la consulta, comprobemos el monto de la orden para
corroborar que caiga en el rango adecuado para incluir en las tablas BIGORDERS o
SMALLORDERS.
Dependiendo de la cantidad, debemos INSERTAR la fila apropiada en la tabla BIGORDERS
o SMALLORDERS.
Repitamos los pasos 2 y 3 hasta que se agoten todas las filas de los resultados de la
consulta.
Confirmemos las actualizaciones a la base de datos.
select amount, company, name from orders, customers, salesreps where cust = cust_num
begin
loop
/* Check for big orders and handle */ elsif (curs_row.amount > 10000.00) then insert into
bigorders
La tabla 5 muestra un procedimiento almacenado de Oracle que realiza este método. El cursor
que define la consulta se define temprano en el procedimiento y se le asigna el nombre
O_CURSOR. La variable CURS_ROW se define como un tipo de fila de Oracle. Es una variable
de fila estructurada de Oracle con componentes individuales (como una estructura en lenguaje
C). Al declarar que tiene el mismo tipo de fila que el cursor, los componentes individuales de
CURS_ROW tienen los mismos tipos de datos y nombres que las columnas de resultados de la
consulta del cursor.
La consulta descrita por el cursor se realiza, en realidad, mediante el bucle FOR con base en el
cursor. Básicamente, le dice al DBMS que realice la consulta descrita por el cursor (equivalente a
la instrucción OPEN en SQL incorporado) antes de iniciar el procesamiento de bucle. El DBMS,
entonces, ejecuta el bucle FOR repetidamente, busca una fila de resultados de consulta en la
parte superior del bucle, coloca los valores de columna en la variable CURS_ROW y luego
ejecuta las instrucciones en el cuerpo del bucle. Cuando no se busquen más filas de resultados
de consulta, el cursor se cierra y el procesamiento continúa después del bucle.
Disparadores
update offices
END;
El cuerpo de este disparador le dice al DBMS que, para cada nueva fila insertada en la tabla,
debería ejecutar la instrucción UPDATE especificada para la tabla OFFICES. El valor QUOTA de
la fila SALESREPS recién insertada se denomina NEW.QUOTA dentro del cuerpo del disparador.
Actividad de repaso
¿Las funciones y los procedimientos almacenados difieren solo en la
cantidad de parámetros?
Verdadero.
Falso.
Justificación
Before update
begin
end;
begin
end;
create Disparador dur_upd_ord before update of amount on orders referencing old as pre new as
post
values (:pre.cust,
:pre.order_date,
:pre.amount,
:post.amount);
values (:pre.cust,
:pre.order_date,
:pre.amount,
Tipos de errores
Errores en tiempo de compilación: las comillas mal colocadas, las palabras clave
de SQL mal escritas y los errores similares en sentencias de SQL embebido son
detectados por el precompilador de SQL e informados al programador.
Errores en tiempo de ejecución: el intento de insertar un valor de datos no válido o
la falta de permisos para actualizar una tabla solo se puede detectar en tiempo de
ejecución. Estos errores deben ser detectados y manejados por el programa de
aplicación. En los programas de SQL embebido, el DBMS informa al programa de
aplicación de errores de ejecución a través de un código de error devuelto. Si se
detecta un error, están disponibles una descripción más detallada del error y otra
información sobre la sentencia que acaba de ejecutarse a través de información de
diagnóstico adicional.
A medida que el DBMS ejecuta cada sentencia de SQL embebido, establece el valor de la
variable SQLCODE en el SQLCA (área de comunicaciones de SQL) para indicar el estado de la
sentencia:
Se puede decir que la aparición del término NoSQL aparece con la llegada de la web 2.0,
ya que hasta ese momento solo subían contenido a la red aquellas empresas que tenían
un portal, pero con la llegada de aplicaciones como Facebook, Twitter o YouTube,
cualquier usuario podía subir contenido, provocando así un crecimiento exponencial de los
datos. (Acens, 2014, https://bit.ly/2OTiVgi)
Es en este momento cuando empiezan a aparecer los primeros problemas de la gestión de toda
esa información almacenada en bases de datos relacionales. En un principio, para solucionar
estos problemas de accesibilidad, las empresas optaban por utilizar un mayor número de
máquinas, pero pronto se dieron cuenta de que esto no solucionaba el problema, además de que
resultaba ser una solución muy cara.
La otra solución era la creación de sistemas pensados para un uso específico que con el
paso del tiempo han dado lugar a soluciones robustas, apareciendo así el movimiento
NoSQL. Por lo tanto, hablar de bases de datos NoSQL es hablar de estructuras que nos
permiten almacenar información en aquellas situaciones en las que las bases de datos
relacionales generan ciertos problemas debido principalmente a problemas de
escalabilidad y rendimiento donde se dan cita miles de usuarios concurrentes y con
millones de consultas diarias. Además de lo comentado anteriormente, las bases de datos
NoSQL son sistemas de almacenamiento de información que no cumplen con el esquema
entidad–relación. Tampoco utilizan una estructura de datos en forma de tabla donde se
van almacenando los datos, sino que para el almacenamiento hacen uso de otros
formatos como clave–valor, mapeo de columnas o grafos. (Acens, 2014,
https://bit.ly/2OTiVgi)
En este tipo de bases, la información se representa mediante objetos, de la misma forma que son
representados en los lenguajes de programación orientada a objetos (POO), como ocurre en
JAVA, C# o Visual Basic .NET. Algunos ejemplos de este tipo de bases de datos son Zope,
Gemstone o Db4o.
Para crear una base de datos en MongoDB hay que usar, con la sentencia use, una base
de datos o colección que todavía no existe.
use peliculas;
Ahora, vamos a insertar una película en la colección y en ese momento esta se creará:
db.peliculas.save({titulo:'Batman el caballero oscuro'}).
Podemos hacer una consulta para ver que hay dentro de la colección db.peliculas.find().
Podemos ver el resto de base de datos creadas con el comando: show dbs. (Robles,
2016, https://bit.ly/3238uMp)
Ventajas
Está más adaptado su uso y Su escalabilidad y su carácter
baratos. distribuidas.
gestionar. relación.
Desventajas
La atomicidad de las No todas las bases de datos
no sean Linux.
Cuando los datos deben ser consistentes sin dar posibilidad al error de utilizar una base de
datos relacional, SQL.
Cuando nuestro presupuesto no se puede permitir grandes máquinas y debe destinarse a
máquinas de menor rendimiento, NoSQL.
Cuando las estructuras de datos que manejamos son variables, NoSQL.
Cuando hay que analizar grandes cantidades de datos en modo lectura, NoSQL.
Cuando hay que capturar y procesar eventos, NoSQL.
Cuando se trata de tiendas online con motores de inteligencia complejos, NoSQL.
Actividad de repaso
¿Cuáles de las siguientes opciones corresponden a tipos de bases de
datos NoSQL?
Clave-valor.
Documentales.
Dibujadas.
Grafo.
Pictóricas.
Justificación
Microactividades
La plataforma que utilizaremos será: https://extendsclass.com/postgresql/e176003
Si utilizamos pgAdmin todas las tablas, datos, funciones, procedimientos almacenados y triggers
serán guardados en nuestra computadora de forma tal que podremos acceder a ellos
indiferentemente si cerramos el programa o reiniciamos nuestros sistemas.
En el caso de utilizar la herramienta online, deberán guardar las consultas que vayan realizando,
ya que, al cerrar el navegador se perderán todos los datos y se deberá copiar, pegar y ejecutar
las consultas que ya habíamos ejecutado (y que guardado en un documento de texto cualquiera
de los disponibles). De esta forma podrán avanzar en las próximas microactividades sin
necesidad de volver a escribirlas una a una nuevamente.
A lo largo de todas las microactividades se debe crear y trabajar sobre un sistema para una
universidad.
Desde la universidad Puls-ar nos solicitan llevar el registro de los alumnos y las materias que
ellos cursan. Cuando los alumnos se inscriben se les solicita su DNI, nombre, apellido y dirección
de correo electrónico.
Tabla 7. Ejercicio
3. Crear una tabla llamada alumnos_logs idem de alumnos, pero agregando un campo llamado
fecha para registrar un tipo de datos fecha y hora. Esta tabla, a su vez, no debe tener un
identificador único. La utilidad de esta tabla la definiremos más adelante para poder registrar los
cambios realizados sobre los alumnos.
4. Crear un procedimiento almacenado que luego utilizaremos para llamar desde un trigger. La
idea de este procedimiento almacenado es registrar las modificaciones ocurridas sobre la tabla
alumnos cuando sus registros se actualicen. Estas modificaciones las guardaremos dentro de
nuestra nueva tabla alumnos_logs. Este procedimiento almacenado debe llamarse
alumnos_update_trigger_fnc().
5. Crear el trigger que monitoree nuestras tablas alumnos. En caso de actualización de algún
registro, deberá llamar al procedimiento almacenado anteriormente para ir agregando los
registros en la tabla alumnos_logs.
6. Modificar la tabla de alumnos de forma que se completen mediante el trigger (de forma
automática) los registros en la tabla alumnos_logs para obtener el siguiente esquema de la
misma. Recordar que la columna fecha tendrá otros valores ya que se registrará la fecha hora del
momento en que ejecuten las actualizaciones.
Tabla 8. Ejercicio
7. Realizar un select de la tabla log que muestre los resultados de la actualización realizada por el
disparador o trigger ordenado por fecha.
Resolución microactividad
Video de habilidades
Fuente: HolaMundo. (2019). ¿Qué es sql y nosql? ¿Cuáles son sus diferencias y cuándo deberías utilizarlos? [Video de YouTube].
Recuperado de https://www.youtube.com/watch?v=zmXl2dOGWL8
En el video podemos ampliar y conocer más sobre las diferentes características que poseen las
bases SQL y las NoSQL: rendimiento, capacidad, seguridad y disponibilidad. Tener claridad sobre
estas diferencias es muy importante ya que nos permitirá elegir en qué situaciones utilizar cada
tipo de base.
Preguntas de habilidades
Dos de las siguientes son características de las bases NoSQL:
Escalabilidad.
Atomicidad.
Inseguridad.
Justificación
Confiabilidad.
Integridad/Consistencia.
Escalabilidad.
Velocidad.
Justificación
Verdadero.
Falso.
Justificación
Relacionales.
Documentales.
Grafo.
SiSQL.
Justificación
Las bases de datos NoSQL son más eficientes en las ……. de grandes
cantidades de datos, respecto de las relacionales.
Escrituras.
Actualización.
Lecturas.
Eliminación.
Justificación
Cierre
En este módulo estudiamos SQL avanzado y NoSQL: sus diferencias, similitudes y para que
podemos utilizar a cada uno de ellos. Con el cierre de este módulo tendrás nuevas herramientas
necesarias para poder desarrollarte en el campo profesional ¡felicitaciones!
Glosario
Referencias
Acens, (2014). Bases de datos NoSQL. Qué son y tipos que nos podemos encontrar.
Recuperado de https://www.acens.com/wp-content/images/2014/02/bbdd-nosql-wp-acens.pdf
Pandorafms, (2015). NoSQL vs SQL; principales diferencias y cuándo elegir cada una de ellas.
Recuperado de https://pandorafms.com/blog/es/nosql-vs-sql-diferencias-y-cuando-elegir-cada-
una/
https://victorroblesweb.es/2016/12/24/crear-una-base-datos-mongodb/