El documento presenta información sobre programación en el servidor en bases de datos. Explica conceptos como procedimientos almacenados, funciones y disparadores, y cómo crearlos usando SQL. Detalla los pasos para definir parámetros, declarar variables y desarrollar procedimientos almacenados para realizar operaciones CRUD (crear, leer, actualizar y eliminar). El objetivo es capacitar a los estudiantes en programación en SQL para resolver requerimientos de la vida real.
2da. Clase Mecanografía e introducción a Excel (2).pptx
DB1 Unidad 5: SQL Avanzado
1. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
1
03/03/2022
Programación en el servidor
Unidad 5
Material docente compilado por el profesor Ph.D. Franklin Parrales Bravo para
uso de los cursos de Bases de Datos
2. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
2
03/03/2022
Objetivo general de la Unidad 5
Capacitar al estudiante para crear procedimientos almacenados,
funciones y disparadores haciendo uso de los elementos, sentencias y
estructura de programación adecuados para la programación en SQL,
que le permitan resolver requerimientos de la vida real.
3. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
3
03/03/2022
Contenido
▪ Procedimientos almacenados
▪ Funciones
▪ Disparadores
4. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
4
03/03/2022
Procedimientos almacenados
(Stored procedures)
▪ Los procedimientos almacenados (PAs) son un
conjunto de instrucciones que permiten gestionar de la
mejor manera la carga de trabajo entrante y saliente en
un entorno donde varios programas solicitan el acceso
a los datos y su almacenamiento dependerá del tipo de
gestor de bases de datos que estemos usando.
▪ También varía la sintaxis al crear un procedimiento
almacenado, pero en el caso de MYSQL se realiza de
la siguiente forma:
CREATE PROCEDURE sp_name ([parameter[,...]])
[characteristic ...] routine_body
5. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
5
03/03/2022
Procesamiento inicial de los PAs
Se almacena en la tabla
mysql.proc
El plan compilado se
coloca en la caché de
procedimientos
Compilación
Optimización
Creación
Ejecución
(por primera vez
o recompilación)
Análisis
Para listar stored procedures en MySQL se deben utilizar cualquiera de las consultas:
show procedure status;
select * from mysql.proc;
6. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
6
03/03/2022
Procesamientos posteriores de los PAs
Plan de ejecución recuperado
Plan sin usar se retira
Plan de consulta Contexto de ejecución
SELECT *
FROM member
WHERE member_no
= ?
Conexión 1
8082
Conexión 2
Conexión 3
24
1003
7. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
7
03/03/2022
Ventajas de los PAs
▪ Compartir la lógica de la aplicación
▪ Evitar exposición de los detalles de las tablas de la
base de datos
▪ Proporcionar mecanismos de seguridad
▪ Mejorar el rendimiento
▪ Reducir el tráfico de red
8. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
8
03/03/2022
Ejecución de PAs
▪ Ejecución de un procedimiento almacenado por
separado
CALL StoredProcedureName();
9. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
9
03/03/2022
Creación de PAs
▪ Donde:
▪ parameter: [ IN | OUT | INOUT ] param_name type
▪ type: Cualquier tipo de dato válido para MySql.
▪ routine_body: comandos SQL válidos
CREATE PROCEDURE sp_name ([ parameter[ ,…] ] )
routine_body
10. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
10
03/03/2022
Creación de PAs: BEGIN-END
▪ La sintaxis BEGIN ... END se utiliza para escribir sentencias
compuestas que pueden aparecer en el interior de procedimientos
almacenados.
▪ Una sentencia compuesta puede contener múltiples sentencias,
encerradas por las palabras BEGIN y END.
▪ lista_sentencias es una lista de una o más sentencias.
▪ Cada sentencia dentro de lista_sentencias debe terminar con un
punto y como (;) delimitador de sentencias.
[etiqueta_inicio:] BEGIN
[lista_sentencias]
END [etiqueta_fin]
11. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
11
03/03/2022
Creación de PAs: DELIMITER
▪ El punto y coma (;) es el delimitador por defecto.
▪ Los procedimientos almacenados y funciones pueden contener
varias sentencias que terminan con este delimitador.
▪ Se debe indicar a MySQL que temporalmente NO lo usaremos
como carácter delimitador, eso lo haremos usando la sentencia
DELIMITER.
12. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
12
03/03/2022
Recordando… operaciones CRUD
▪ C (create): crear, ingresar, registrar, agregar
▪ R (read): consultar, listar, imprimir, generar Rep.
▪ U (update): actualizar, modificar
▪ D (delete): eliminar
13. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
13
03/03/2022
Creación de PAs
▪ Utilice la instrucción CREATE PROCEDURE para crearlos en la
base de datos activa
DELIMITER $$
CREATE PROCEDURE SP_AGREGAR_CLIENTE
(IN pnomcliente VARCHAR(100),
IN papellidopaterno VARCHAR(50),
IN papellidomaterno VARCHAR(50), IN pdni CHAR(8),
IN pcelular CHAR(9), IN ptelefono CHAR(6),
IN pcorreo VARCHAR(50), IN pidestado INT)
BEGIN
INSERT INTO cliente VALUES
(null, pnomcliente, papellidopaterno, papellidopaterno,
pdni,pcelular, ptelefono, pcorreo, pidestado);
END$$
DELIMITER ;
C
14. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
14
03/03/2022
Creación de PAs
DELIMITER $$
CREATE PROCEDURE SP_LISTAR_CLIENTE()
BEGIN
SELECT
c.idcliente, c.nomcliente, c.apellidopaterno,
c.apellidomaterno,
c.dni, c.celular, c.telefono, c.correo, e.nomestado
FROM cliente c INNER JOIN estado e
ON e.idestado=c.idestado;
END$$
DELIMITER ;
R
15. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
15
03/03/2022
Creación de PAs
DELIMITER $$
CREATE PROCEDURE SP_ACTUALIZAR_CLIENTE
(IN pidcliente INT, IN pnomcliente VARCHAR(100),
IN papellidopaterno VARCHAR(50),
IN papellidomaterno VARCHAR(50),
IN pdni CHAR(8), IN pcelular CHAR(9), IN ptelefono CHAR(6),
IN pcorreo VARCHAR(50), IN pidestado INT)
BEGIN
UPDATE cliente SET nomcliente=pnomcliente,
apellidopaterno=papellidopaterno,
apellidomaterno=papellidomaterno,
dni=pdni,celular=pcelular,telefono=ptelefono,
correo=pcorreo,idestado=pidestado
WHERE idcliente=pidcliente;
END$$
DELIMITER ;
U
16. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
16
03/03/2022
Creación de PAs
DELIMITER $$
CREATE PROCEDURE SP_ELIMINAR_CLIENTE
(IN pidcliente INT)
BEGIN
DELETE
FROM cliente
WHERE idcliente=pidcliente
END$$
DELIMITER ;
D
17. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
17
03/03/2022
Creación de PAs: Definición de
un parámetro
▪ En esta sintaxis:
▪ Primero, especifique el modo del parámetro, que puede ser
IN, OUT o INOUT según el propósito del parámetro en el
procedimiento almacenado.
▪ En segundo lugar, especifique el nombre del parámetro. El
nombre del parámetro debe seguir las reglas de
nomenclatura del nombre de la columna en MySQL.
▪ En tercer lugar, especifique el tipo de datos y la longitud
máxima del parámetro.
[IN | OUT | INOUT] parameter_name datatype[(length)]
18. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
18
03/03/2022
Creación de PAs: parámetro IN
▪ IN es el modo predeterminado. Cuando define un
parámetro IN en un procedimiento almacenado, el
programa que llama tiene que pasar un argumento al
PA.
▪ Además, el valor de un parámetro IN está protegido.
Significa que incluso si cambia el valor del parámetro
IN dentro del procedimiento almacenado, su valor
original no cambia después de que finaliza el
procedimiento almacenado.
▪ En otras palabras, el procedimiento almacenado solo
funciona en la copia del parámetro IN.
19. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
19
03/03/2022
Creación de PAs: parámetro IN
▪ El siguiente ejemplo crea PA que encuentra todas las
oficinas que se ubican en un país especificado por el
parámetro de entrada countryName:
DELIMITER //
CREATE PROCEDURE GetOfficeByCountry(
IN countryName VARCHAR(255)
)
BEGIN
SELECT *
FROM offices
WHERE country = countryName;
END //
DELIMITER ;
20. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
20
03/03/2022
Creación de PAs: parámetro IN
▪ Supongamos que desea encontrar oficinas
ubicadas en los EE. UU., necesita pasar un
argumento (EE. UU.) al PA como se muestra en la
siguiente consulta:
CALL GetOfficeByCountry('USA');
21. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
21
03/03/2022
Creación de PAs: parámetro IN
▪ Debido a que countryName es el parámetro IN,
debe pasar un argumento. Si no lo hace, obtendrá
un error:
CALL GetOfficeByCountry();
Error Code: 1318. Incorrect number of arguments for
PROCEDURE classicmodels.GetOfficeByCountry;
expected 1, got 0
22. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
22
03/03/2022
Creación de PAs: parámetro OUT
▪ El valor de un parámetro OUT se puede cambiar
dentro del procedimiento almacenado y su nuevo
valor se devuelve al programa que ha llamado (call)
al PA.
▪ Tenga en cuenta que el PA no puede acceder al
valor inicial del parámetro OUT cuando se inicia.
23. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
23
03/03/2022
Creación de PAs: parámetro OUT
▪ El siguiente PA devuelve el número de pedidos por
estado del pedido.
DELIMITER $$
CREATE PROCEDURE GetOrderCountByStatus (
IN orderStatus VARCHAR(25),
OUT total INT
)
BEGIN
SELECT COUNT(orderNumber)
INTO total
FROM orders
WHERE status = orderStatus;
END$$
DELIMITER ;
24. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
24
03/03/2022
Creación de PAs: parámetro OUT
▪ El PA GetOrderCountByStatus() tiene dos parámetros:
▪ El orderStatus: es el parámetro IN que especifica el estado
de los pedidos a devolver.
▪ El total: es el parámetro OUT que almacena el número de
pedidos en un estado específico.
▪ Para encontrar la cantidad de pedidos que ya se
enviaron, llame a GetOrderCountByStatus y pase el
estado del pedido como Enviado, y también pase una
variable de sesión ( @total ) para recibir el valor
devuelto.
CALL GetOrderCountByStatus('Shipped',@total);
SELECT @total;
25. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
25
03/03/2022
Creación de PAs: parámetro OUT
▪ Para obtener la cantidad de pedidos que están en
proceso, llame al PA GetOrderCountByStatus de la
siguiente manera:
CALL GetOrderCountByStatus('in process',@total);
SELECT @total AS total_in_process;
26. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
26
03/03/2022
Creación de PAs: parámetro INOUT
▪ Un parámetro INOUT es una combinación de
parámetros IN y OUT.
▪ Significa que el programa que llama puede pasar el
argumento, y el procedimiento almacenado puede
modificar el parámetro INOUT y devolver el nuevo
valor al programa que llama el PA.
27. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
27
03/03/2022
Creación de PAs: parámetro INOUT
▪ En este ejemplo, el procedimiento almacenado SetCounter() acepta
un parámetro INOUT (counter) y un parámetro IN (inc). Incrementa el
contador (counter) por el valor de especificado por el parámetro inc.
DELIMITER $$
CREATE PROCEDURE SetCounter(
INOUT counter INT,
IN inc INT
)
BEGIN
SET counter = counter + inc;
END$$
DELIMITER ;
28. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
28
03/03/2022
Creación de PAs: parámetro INOUT
▪ Estas declaraciones ilustran cómo llamar al procedimiento
almacenado SetSounter:
SET @counter = 1;
CALL SetCounter(@counter,1); -- 2
CALL SetCounter(@counter,1); -- 3
CALL SetCounter(@counter,5); -- 8
SELECT @counter; -- 8
▪ Aquí está la salida:
29. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
29
03/03/2022
Creación de PAs: DECLARE
▪ El comando DECLARE se usa para definir variables
locales que se utilizarán dentro de los PAs.
▪ DECLARE puede usarse sólo dentro de comandos
compuestos BEGIN ... END y deben ser su inicio, antes de
cualquier otro comando.
DECLARE variable_name datatype(size) [DEFAULT default_value];
30. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
30
03/03/2022
Creación de PAs: DECLARE
▪ En esta sintaxis:
▪ Primero, especifique el nombre de la variable después de la
palabra clave DECLARE. El nombre de la variable debe seguir
las reglas de nomenclatura de los nombres de columna de la
tabla MySQL.
▪ En segundo lugar, especifique el tipo de datos y la longitud de la
variable. Una variable puede tener cualquier tipo de datos de
MySQL, como INT, VARCHAR y DATETIME.
▪ Tercero, asigne a una variable un valor predeterminado usando
la opción DEFAULT. Si declara una variable sin especificar un
valor predeterminado, su valor es NULL.
DECLARE variable_name datatype(size) [DEFAULT default_value];
31. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
31
03/03/2022
Creación de PAs: DECLARE
▪ El siguiente ejemplo declara una variable denominada
VentaTotal con el tipo de datos DEC(10,2) y el valor
predeterminado 0.0 de la siguiente manera:
▪ MySQL le permite declarar dos o más variables que
comparten el mismo tipo de datos usando una sola
instrucción DECLARE. El siguiente ejemplo declara dos
variables enteras x e y, y establece sus valores
predeterminados en cero.
DECLARE totalSale DEC(10,2) DEFAULT 0.0;
DECLARE x, y INT DEFAULT 0;
32. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
32
03/03/2022
Creación de PAs: DECLARE
▪ Una vez que se declara una variable, está lista para usar.
Para asignar un valor a una variable, utiliza la instrucción
SET:
▪ Por ejemplo:
▪ El valor de la variable total es 10 después de la asignación.
▪ Además de la declaración SET, puede usar la declaración
SELECT INTO para asignar el resultado de una consulta a
una variable como se muestra en el siguiente ejemplo:
SET variable_name = value;
DECLARE total INT DEFAULT 0;
SET total = 10;
DECLARE productCount INT DEFAULT 0;
SELECT COUNT(*)
INTO productCount
FROM products;
33. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
33
03/03/2022
Creación de PAs: DECLARE
▪ En este ejemplo:
▪ Primero, declare una variable llamada productCount e
inicialice su valor en 0.
▪ Luego, use la instrucción SELECT INTO para asignar a
la variable productCount la cantidad de productos
seleccionados de la tabla de productos.
DECLARE productCount INT DEFAULT 0;
SELECT COUNT(*)
INTO productCount
FROM products;
34. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
34
03/03/2022
Creación de PAs: DECLARE
▪ Una variable tiene su propio ámbito que define su duración. Si
declara una variable dentro de un procedimiento almacenado, estará
fuera del alcance cuando llegue la instrucción END del
procedimiento almacenado.
▪ Cuando declara una variable dentro del bloque BEGIN END, estará
fuera del alcance si se alcanza el END.
▪ MySQL le permite declarar dos o más variables que comparten el
mismo nombre en diferentes ámbitos. Porque una variable solo es
efectiva en su alcance. Sin embargo, declarar variables con el
mismo nombre en diferentes ámbitos no es una buena práctica de
programación.
▪ Una variable cuyo nombre comienza con el signo @ es una variable
de sesión. Está disponible y accesible hasta que finaliza la sesión.
35. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
35
03/03/2022
Creación de PAs: DECLARE
▪ El siguiente ejemplo ilustra cómo declarar y usar una
variable en un PA:
DELIMITER $$
CREATE PROCEDURE GetTotalOrder()
BEGIN
DECLARE totalOrder INT DEFAULT 0;
SELECT COUNT(*)
INTO totalOrder
FROM orders;
SELECT totalOrder;
END$$
DELIMITER ;
36. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
36
03/03/2022
Creación de PAs: DECLARE
¿Cómo funciona?
▪ Primero, declare una variable totalOrder con un valor
predeterminado de cero. Esta variable contendrá el número de
pedidos de la tabla de pedidos.
▪ En segundo lugar, use la sentencia SELECT INTO para asignar a
la variable totalOrder el número de pedidos seleccionados de la
tabla de pedidos:
▪ Tercero, seleccione el valor de la variable totalOrder.
DECLARE totalOrder INT DEFAULT 0;
SELECT COUNT(*)
INTO totalOrder
FROM orders;
SELECT totalOrder;
37. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
37
03/03/2022
Creación de PAs: DECLARE
▪ Esta sentencia llama al procedimiento almacenado
GetTotalOrder():
CALL GetTotalOrder();
▪ Aquí está la salida:
38. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
38
03/03/2022
Creación de PAs: CURSOR
▪ Para manejar un conjunto de resultados dentro de
un procedimiento almacenado, usa un cursor.
▪ Un cursor le permite iterar un conjunto de filas devueltas
por una consulta y procesar cada fila individualmente.
▪ El cursor MySQL es de solo lectura, no desplazable
y asensitive.
39. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
39
03/03/2022
Creación de PAs: CURSOR
▪ Solo lectura: no puede actualizar los datos en la
tabla subyacente a través del cursor.
▪ No desplazable: solo puede obtener filas en el
orden determinado por la instrucción SELECT. No
puede obtener filas en el orden inverso. Además,
no puede omitir filas ni saltar a una fila específica
en el conjunto de resultados.
40. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
40
03/03/2022
Creación de PAs: CURSOR
▪ Asensitive: hay dos tipos de cursores: cursor
asensitive y cursor insensitive.
▪ Un cursor asensitive apunta a los datos reales, mientras que
un cursor insensitive utiliza una copia temporal de los datos.
▪ Un cursor asensitive funciona más rápido que un cursor
insensitive porque no tiene que hacer una copia temporal de
los datos.
▪ Sin embargo, cualquier cambio que se realice en los datos
de otras conexiones afectará los datos que utiliza un cursor
asensitive; por lo tanto, es más seguro si no actualiza los
datos que utiliza un cursor asensitive.
▪ El cursor de MySQL es asensitive.
41. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
41
03/03/2022
Creación de PAs: CURSOR
▪ Puede usar cursores MySQL en PA, funciones y disparadores.
▪ Primero, declare un cursor usando la instrucción DECLARE:
▪ La declaración del cursor debe estar después de cualquier
declaración de variable. Si declara un cursor antes de las
declaraciones de variables, MySQL generará un error. Un cursor
siempre debe asociarse con una instrucción SELECT.
▪ A continuación, abra el cursor mediante la instrucción OPEN. La
sentencia OPEN inicializa el conjunto de resultados para el cursor,
por lo tanto, debe llamar a la sentencia OPEN antes de obtener
filas del conjunto de resultados.
DECLARE cursor_name CURSOR FOR SELECT_statement;
OPEN cursor_name;
42. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
42
03/03/2022
Creación de PAs: CURSOR
▪ Luego, use la instrucción FETCH para recuperar la siguiente
fila señalada por el cursor y mueva el cursor a la siguiente
fila en el conjunto de resultados.
▪ Después de eso, verifique si hay alguna fila disponible antes
de buscarla.
▪ Finalmente, desactive el cursor y libere la memoria asociada
a él usando la instrucción CLOSE:
▪ Es una buena práctica cerrar siempre un cursor cuando ya
no se usa.
FETCH cursor_name INTO variables list;
CLOSE cursor_name;
43. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
43
03/03/2022
Creación de PAs: CURSOR
▪ Cuando trabaje con el cursor MySQL, también debe
declarar un controlador(handler) NOT FOUND para
manejar la situación en la que el cursor no pudo
encontrar ninguna fila.
▪ Porque cada vez que llama a la declaración FETCH, el
cursor intenta leer la siguiente fila en el conjunto de
resultados. Cuando el cursor llega al final del conjunto de
resultados, no podrá obtener los datos y se generará una
condición. El controlador se utiliza para manejar esta
condición.
▪ Para declarar un controlador NOT FOUND, utilice la
siguiente sintaxis:
DECLARE CONTINUE HANDLER FOR NOT FOUND SET finished = 1;
44. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
44
03/03/2022
Creación de PAs: CURSOR
▪ Finished es una variable para indicar que el cursor
ha llegado al final del conjunto de resultados.
Tenga en cuenta que la declaración del controlador
debe aparecer después de la declaración de la
variable y el cursor dentro de los PAs.
▪ El siguiente diagrama ilustra cómo funciona el
cursor MySQL.
45. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
45
03/03/2022
Creación de PAs: CURSOR
▪ Desarrollaremos un PA que crea una lista de correo
electrónico de todos los empleados en la tabla de
empleados en la base de datos de ejemplo.
46. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
46
03/03/2022
Creación de PAs: CURSOR
▪ Primero, declare algunas variables, un cursor para recorrer
los correos electrónicos de los empleados y un controlador
NOT FOUND:
DECLARE finished INTEGER DEFAULT 0;
DECLARE emailAddress VARCHAR(100) DEFAULT "";
-- declare cursor for employee email
DEClARE curEmail
CURSOR FOR
SELECT email FROM employees;
-- declare NOT FOUND handler
DECLARE CONTINUE HANDLER
FOR NOT FOUND SET finished = 1;
47. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
47
03/03/2022
Creación de PAs: CURSOR
▪ A continuación, abra el cursor mediante la instrucción OPEN:
▪ Luego, repita la lista de correo electrónico y concatene todos los
correos electrónicos donde cada correo electrónico esté separado
por un punto y coma (;):
OPEN curEmail;
getEmail: LOOP
FETCH curEmail INTO emailAddress;
IF finished = 1 THEN
LEAVE getEmail;
END IF;
-- build email list
SET emailList = CONCAT(emailAddress,";",emailList);
END LOOP getEmail;
48. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
48
03/03/2022
Creación de PAs: CURSOR
▪ Después de eso, dentro del bucle, usamos la
variable finished para verificar si hay un correo
electrónico en la lista para terminar el bucle.
▪ Finalmente, cierre el cursor usando la instrucción
CLOSE:
▪ El procedimiento almacenado createEmailList es el
siguiente:
CLOSE curEmail;
49. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
49
03/03/2022
DELIMITER $$
CREATE PROCEDURE createEmailList (INOUT emailList VARCHAR(4000))
BEGIN
DECLARE finished INTEGER DEFAULT 0;
DECLARE emailAddress VARCHAR(100) DEFAULT "";
-- declare cursor for employee email
DEClARE curEmail
CURSOR FOR
SELECT email FROM employees;
-- declare NOT FOUND handler
DECLARE CONTINUE HANDLER
FOR NOT FOUND SET finished = 1;
OPEN curEmail;
getEmail: LOOP
FETCH curEmail INTO emailAddress;
IF finished = 1 THEN
LEAVE getEmail;
END IF;
-- build email list
SET emailList = CONCAT(emailAddress,";",emailList);
END LOOP getEmail;
CLOSE curEmail;
END$$
DELIMITER ;
50. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
50
03/03/2022
Creación de PAs: CURSOR
▪ Puede probar el procedimiento almacenado
createEmailList utilizando el siguiente script:
SET @emailList = "";
CALL createEmailList(@emailList);
SELECT @emailList;
51. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
51
03/03/2022
Creación de PAs: Recomendaciones
▪ Crear un procedimiento almacenado por tarea
▪ Crear, probar y solucionar problemas
▪ Evite sp_Prefix en los nombres de procedimientos
almacenados
▪ Utilice la misma configuración de conexión para todos los
procedimientos almacenados
▪ Reduzca al mínimo la utilización de procedimientos
almacenados temporales
▪ No elimine nunca directamente las entradas de
mysql.proc
52. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
52
03/03/2022
Eliminar PAs
▪ La sentencia DROP PROCEDURE elimina un procedimiento almacenado
creado por la sentencia CREATE PROCEDURE.A continuación se muestra
la sintaxis de la instrucción DROP PROCEDURE:
▪ En esta sintaxis:
▪ Primero, especifique el nombre del procedimiento almacenado que desea
eliminar después de las palabras clave DROP PROCEDURE.
▪ En segundo lugar, use la opción IF EXISTS para descartar condicionalmente
el procedimiento almacenado si existe.
▪ Cuando elimina un procedimiento que no existe sin usar la opción IF
EXISTS, MySQL emite un error. En este caso, si usa la opción IF EXISTS,
MySQL emite una advertencia en su lugar.
▪ Tenga en cuenta que debe tener el privilegio ALTER ROUTINE del
procedimiento almacenado para eliminarlo.
DROP PROCEDURE [IF EXISTS] stored_procedure_name;
53. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
53
03/03/2022
Transacciones dentro de PAs
▪ Podemos utilizar el manejo de errores para decidir
si hacemos ROLLBACK de una transacción.
▪ En el siguiente ejemplo vamos a capturar los
errores que se produzcan de tipo SQLEXCEPTION
y SQLWARNING…
54. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
54
03/03/2022
DELIMITER $$
CREATE PROCEDURE transaccion_en_mysql()
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION
BEGIN
-- ERROR
ROLLBACK;
END;
DECLARE EXIT HANDLER FOR SQLWARNING
BEGIN
-- WARNING
ROLLBACK;
END;
START TRANSACTION;
-- Sentencias SQL
COMMIT;
END
$$
55. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
55
03/03/2022
DELIMITER $$
CREATE PROCEDURE transaccion_en_mysql()
BEGIN
DECLARE EXIT HANDLER FOR SQLEXCEPTION, SQLWARNING
BEGIN
-- ERROR, WARNING
ROLLBACK;
END;
START TRANSACTION;
-- Sentencias SQL
COMMIT;
END
$$
Transacciones dentro de PAs
▪ En lugar de tener un manejador para cada tipo de error,
podemos tener uno común para todos los casos.
56. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
56
03/03/2022
Recuerde que…
▪ Los procedimientos almacenados en realidad no
devuelven la salida directamente.
▪ Pueden ejecutar instrucciones de selección dentro
del script, pero no tienen valor de retorno.
57. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
57
03/03/2022
Contenido
▪ Procedimientos almacenados
▪ Funciones
▪ Disparadores
58. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
58
03/03/2022
Funciones
▪ Una funcion (FUNCTION) es un procedimiento almacenado
(PROCEDURE).
▪ Difieren de los procedimientos en que:
▪ La lista de parámetros solo puede contener parámetros de
entrada.
▪ IN, OUT o INOUT es solo válido para PAs.
▪ Una función siempre debe retornar un valor del tipo definido en la
declaración de la función.
▪ Las funciones pueden ser llamadas dentro de sentencias SQL
▪ Una función no puede devolver un registro de datos.
Para listar funciones en MySQL se deben utilizar la siguiente consulta:
show function status;
CREATE FUNCTION sp_name ([parameter[,...]])
RETURNS type routine_body
59. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
59
03/03/2022
Creando funciones:
▪ Si requiero utilizar esta función…
▪ SELECT Cubo(4),….
▪ SELECT Cubo(numero) FROM tabla
DELIMITER //
CREATE FUNCTION Cubo(Numero FLOAT)
RETURNS FLOAT
BEGIN
DECLARE cubo1 FLOAT;
SET cubo1=(Numero * Numero * Numero);
RETURN cubo1;
END;
//
60. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
60
03/03/2022
Creando funciones:
▪ Si requiero utilizar esta función…
▪ SELECT nota1, nota2, nota3, promedio_normal(nota1, nota2,
nota3) FROM alumno;
DELIMITER //
CREATE FUNCTION promedio_normal (numero1 INT,
numero2 INT, numero3 INT) RETURNS FLOAT
BEGIN
DECLARE prom FLOAT;
SET prom=((numero1+numero2+numero3)/3);
RETURN prom;
END;
//
61. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
61
03/03/2022
Creando funciones:
▪ Función que calcula el promedio de 3 notas.
DELIMITER //
CREATE FUNCTION promedio_normal_otro (numero1 INT,
numero2 INT, numero3 INT) RETURNS FLOAT
BEGIN
DECLARE sum INT;
DECLARE prom FLOAT;
SET sum=numero1+numero2+numero3;
SET prom=(sum/3);
RETURN prom;
END;
//
62. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
62
03/03/2022
Creando funciones:
▪ Promedio de notas con una décima.
DELIMITER //
CREATE FUNCTION promedio_decimas (numero1 FLOAT,
numero2 FLOAT, numero3 FLOAT) RETURNS FLOAT
BEGIN
DECLARE prom FLOAT;
SET prom=ROUND(((numero1+numero2+numero3)/3),1);
RETURN prom;
END;
//
63. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
63
03/03/2022
Creando funciones:
▪ Crear una función que calcule el promedio
ponderado de estas 3 notas (decimal).
▪ Ponderación: 20%, 30%, 50%
DELIMITER //
CREATE FUNCTION promedio_ponderado (numero1 FLOAT,
numero2 FLOAT, numero3 FLOAT) RETURNS FLOAT
BEGIN
DECLARE prom FLOAT;
SET prom=ROUND((numero1*0.2+numero2*0.3+numero3*0.5),1);
RETURN prom;
END;
//
64. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
64
03/03/2022
Creando funciones:
▪ Usando una ponderación cualquiera que se de en
el momento.
DELIMITER //
CREATE FUNCTION promedio_ponderado_cual (numero1 FLOAT,
numero2 FLOAT, numero3 FLOAT, p1 INT, p2 INT, p3 INT)
RETURNS FLOAT
BEGIN
DECLARE prom FLOAT;
SET prom=ROUND((numero1*p1/100+numero2*p2/100+
numero3*p3/100),1);
RETURN prom;
END;
//
65. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
65
03/03/2022
Creando funciones:
▪ Ponderaciones suman 1…
▪ Qué pasa si la suma de ponderaciones no suman
1???
▪ Qué se puede hacer?
66. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
66
03/03/2022
Algunas estructuras de control…
▪ BLOQUE IF
IF expresión THEN …
ELSE …
…
END IF;
condicion
SI NO
acciones
acciones
67. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
67
03/03/2022
Algunas estructuras de control…
▪ WHILE
WHILE expresión DO
-- contenido del bucle
END WHILE;
condicion
SI
NO
acciones
Se hace notar que en este tipo de estructura
las acciones pueden no ejecutarse ninguna
vez.
68. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
68
03/03/2022
Algunas estructuras de control…
▪ REPEAT – UNTIL
REPEAT
-- CODE DEL BUCLE
UNTIL variable >= 1
END REPEAT;
condicion
SI
NO
acciones
69. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
69
03/03/2022
Algunas estructuras de control…
▪ CASE (similar al SWITCH o SELEC CASE de algunos lenguajes de
programación)
CASE variable
WHEN 1 THEN -- que hacer en caso de que variable = 1
WHEN 2 THEN -- que hacer en caso de que variable = 2
WHEN x THEN -- que hacer en caso de que variable = x
ELSE -- que hacer en caso de que no se presente alguno de los casos
anteriores
END CASE;
70. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
70
03/03/2022
Creando funciones:
▪ Ponderaciones suman 1…sino promedio=1
DELIMITER //
CREATE FUNCTION promedio_ponderado_if (numero1 FLOAT,
numero2 FLOAT, numero3 FLOAT, p1 INT, p2 INT, p3 INT)
RETURNS FLOAT
BEGIN
DECLARE prom FLOAT;
IF (p1+p2+p3)=100 THEN
SET prom=ROUND((numero1*p1/100+numero2*p2/100+
numero3*p3/100),1);
RETURN prom;
ELSE
SET prom=1;
RETURN prom;
END IF;
END;
//
71. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
71
03/03/2022
Creando funciones:
▪ Recursividad…una función puede llamarse a si
misma…
▪ Sin embargo MySql no permite llamadas recursivas.
▪ Tarea:
▪ Crear una función que calcule el factorial de un numero:
5! = 5*4*3*2*1
72. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
72
03/03/2022
Ejecución de funciones
▪ Ejecución de una función en una instrucción
INSERT
INSERT INTO table1
SELECT sp_test()
73. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
73
03/03/2022
Eliminar funciones
▪ La instrucción DROP FUNCTION descarta una función
almacenada. Esta es la sintaxis de la instrucción DROP
FUNCTION:
▪ En esta sintaxis, especifica el nombre de la función
almacenada que desea eliminar después de las
palabras clave DROP FUNCTION.
▪ La opción IF EXISTS le permite descartar
condicionalmente una función almacenada si existe.
Evita que surja un error si la función no existe.
DROP FUNCTION [IF EXISTS] function_name;
74. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
74
03/03/2022
Contenido
▪ Procedimientos almacenados
▪ Funciones
▪ Disparadores
75. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
75
03/03/2022
Disparadores
(Triggers)
▪ Un trigger, también conocido como disparador (Por su
traducción al español) es un conjunto de sentencias
SQL las cuales se ejecutan de forma automática
cuando ocurre algún evento que modifique a una tabla.
▪ Pero no me refiero a una modificación de estructura,
no, me refiero a una modificación en cuando a los
datos almacenados, es decir, cuando se ejecute una
sentencia INSERT, UPDATE o DELETE.
▪ A diferencia de una función o un store procedure, un
trigger no puede existir sin una tabla asociada.
76. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
76
03/03/2022
Disparadores
(Triggers)
▪ Técnicamente, un trigger es un objeto de una base
de datos que está asociado a una tabla, y que será
activado cuando la acción que tiene asociada tiene
lugar.
▪ El trigger se puede ejecutar cuando tiene lugar una
acción INSERT, UPDATE o DELETE, siendo
posible su ejecución tanto antes como después del
evento.
77. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
77
03/03/2022
Disparadores
(Triggers)
Podemos programar los triggers de tal manera que se ejecuten antes o
después, de dichas sentencias; Dando como resultado seis combinaciones de
eventos.
▪ BEFORE INSERT Acciones a realizar antes de insertar uno más o registros
en una tabla.
▪ AFTER INSERT Acciones a realizar después de insertar uno más o
registros en una tabla.
▪ BEFORE UPDATE Acciones a realizar antes de actualizar uno más o
registros en una tabla.
▪ AFTER UPDATE Acciones a realizar después de actualizar uno más o
registros en una tabla.
▪ BEFORE DELETE Acciones a realizar antes de eliminar uno más o
registros en una tabla.
▪ AFTER DELETE Acciones a realizar después de eliminar uno más o
registros en una tabla.
78. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
78
03/03/2022
Disparadores
(Triggers)
▪ A partir de la versión 5.7.2 de MySQL podemos tener la
n cantidad de triggers asociados a una tabla.
▪ Anteriormente estábamos limitados a tener un máximo de
seis trigger por tabla (Uno por cada combinación evento).
▪ Podemos ver esto como una relación uno a muchos,
una tabla puede poseer muchos triggers y un trigger le
pertenece única y exclusivamente a una tabla.
▪ Algo importante a mencionar es que la sentencia
TRUNCATE no ejecutará un trigger.
79. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
79
03/03/2022
Ventajas de utilizar Triggers
▪ Con los triggers seremos capaces validar todos
aquellos valores los cuales no pudieron ser validados
mediante constraints, asegurando así la integridad de
los datos.
▪ Los triggers nos permitirán ejecutar reglas de negocio.
▪ Utilizando la combinación de eventos nosotros
podemos realizar acciones sumamente complejas.
▪ Los trigger nos permitirán llevar un control de los
cambios realizados en una tabla. Para esto nos
debemos de apoyar de una segunda tabla
(Comúnmente una tabla log).
80. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
80
03/03/2022
Desventajas de utilizar Triggers
▪ Los triggers al ejecutarse de forma automática
puede dificultar llevar un control sobre qué
sentencias SQL fueron ejecutadas.
▪ Los triggers incrementan la sobrecarga del servidor.
▪ Un mal uso de triggers puede tornarse en respuestas
lentas por parte del servidor.
81. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
81
03/03/2022
Creación de Triggers
▪ Antes de crear
un trigger,
vamos a crear
una tabla de
ejemplo.
CREATE TABLE productos (
id INT NOT NULL AUTO_INCREMENT,
nombre VARCHAR(20) NOT NULL,
coste FLOAT NOT NULL DEFAULT 0.0,
precio FLOAT NOT NULL DEFAULT 0.0,
PRIMARY KEY(id)
);
INSERT INTO productos (nombre, coste, precio) VALUES
('Producto A', 4, 8),
('Producto B', 2, 4),
('Producto C', 40, 80);
82. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
82
03/03/2022
Creación de Triggers
▪ Vamos a crear un trigger que actualice
automáticamente el precio de los productos de la
tabla creada en el apartado anterior cada vez que
se actualice su coste.
▪ Le llamaremos actualizarPrecioProducto.
▪ El trigger comprobará si el coste del producto ha
cambiado y, en caso afirmativo, establecerá el
precio del producto con el doble del valor de su
coste.
▪ Para crear el trigger, ejecuta las siguientes
sentencias SQL:
83. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
83
03/03/2022
Creación de Triggers
▪ Lo que hacemos es crear un trigger que se ejecute antes de la
actualización del registro, algo que indicamos con la sentencia “BEFORE
UPDATE ON”.
▪ Luego comprobamos si el coste antiguo del producto difiere del nuevo y, si
es así, actualizamos el precio con el doble del valor de su nuevo coste. Un
negocio redondo.
DELIMITER $$
CREATE TRIGGER 'actualizarPrecioProducto'
BEFORE UPDATE ON 'productos'
FOR EACH ROW
BEGIN
IF NEW.coste <> OLD.coste
THEN
SET NEW.precio = NEW.coste * 2;
END IF ;
END$$
DELIMITER ;
84. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
84
03/03/2022
Cómo utilizar un Trigger:
▪ Una vez hayamos creado el trigger, no tendremos que
hacer absolutamente nada para llamarlo, puesto que el
motor de la base de datos lo invocará
automáticamente cada vez que se actualice un registro de
la tabla de productos.
▪ Sin embargo, sí podemos comprobar el resultado del
trigger actualizando un registro con una
sentencia UPDATE como esta:
▪ Cuando se ejecuta la actualización con la sentencia
UPDATE, se activa también el Trigger, que actualizará el
precio con el doble de su valor, según lo hemos definido.
UPDATE productos SET coste = 5 WHERE id = 1;
SELECT * FROM productos;
85. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
85
03/03/2022
Cómo borrar un Trigger:
▪ Puedes eliminar una trigger haciendo uso de
la sentencia DROP TRIGGER
▪ Por ejemplo, si quieres eliminar el
trigger actualizarPrecioProducto del ejemplo
anterior, tendrás que ejecutar esta sentencia:
DROP TRIGGER actualizarPrecioProducto;
86. Bases de Datos
Ph.D. Franklin Parrales
Carrera de Software
86
03/03/2022
Final de la unidad
Y del curso…. !Muchas gracias
a todos!
Programación en el servidor
Unidad 5