1 00:00:00,000 --> 00:00:13,660 Buenos días a todos. Voy a hacer dos vídeos para introducir un poquito o explicar algunos 2 00:00:13,660 --> 00:00:19,660 aspectos de esta unidad. En esta portada introduce el tema general, cómo hacer que una base 3 00:00:19,660 --> 00:00:25,379 de datos no solo almacene información, sino que además ejecute la lógica de manera automática. 4 00:00:25,379 --> 00:00:38,359 La idea principal es que muchas veces pensamos que la base de datos solo guarda datos y que toda la inteligencia está en la aplicación, pero aquí se plantea otra visión. 5 00:00:38,899 --> 00:00:49,500 Parte de esa inteligencia puede vivir dentro del propio motor de la base de datos usando dos herramientas principales que serían los procedimientos almacenados y los disparadores o los llamados triggers. 6 00:00:50,159 --> 00:00:56,380 En esta presentación voy a explicar cómo una base de datos puede hacer mucho más que guardar datos. 7 00:00:56,640 --> 00:01:05,939 Puede calcular, validar, automatizar tareas y reaccionar ante cambios sin que la aplicación tenga que controlar todo manualmente. 8 00:01:06,140 --> 00:01:12,359 Para ello se usan dos mecanismos muy importantes que son los procedimientos almacenados y los disparadores. 9 00:01:12,359 --> 00:01:28,200 Las ideas básicas que hay que remarcar serían automatizar una base de datos, que significaría mover parte de la lógica al servidor SQL. Eso puede mejorar la organización, la reutilización y, en algunos casos, el rendimiento. 10 00:01:28,200 --> 00:01:49,900 Y no se trata de sustituir totalmente a la aplicación, sino de repartir responsabilidades de forma inteligente. Por ejemplo, en una tienda online, cuando se registra una venta, la base de datos podría calcular automáticamente una comisión, actualizar un stock o registrar una auditoría sin que el programador tenga que repetir esa lógica en cada pantalla o módulo. 11 00:01:49,900 --> 00:02:02,680 Bueno, el paradigma de la lógica interna vemos aquí a la izquierda la lógica en la aplicación, en el que la aplicación vemos que es compleja. 12 00:02:03,280 --> 00:02:08,759 La base de datos actúa como almacenamiento simple y toda la carga de procesamiento recae en la aplicación. 13 00:02:09,139 --> 00:02:10,979 Hay más tráfico entre cliente y servidor. 14 00:02:11,539 --> 00:02:13,879 A la derecha vemos la lógica en la base de datos. 15 00:02:14,080 --> 00:02:20,719 La aplicación es más ligera, la base de datos es inteligente, los procedimientos almacenados viven dentro del motor 16 00:02:20,719 --> 00:02:26,139 y se pueden cambiar ciertas reglas sin modificar tanto la aplicación principal. 17 00:02:27,759 --> 00:02:33,919 Por lo tanto, en el primer modelo la aplicación hace cálculos, valida, transforma datos, 18 00:02:34,099 --> 00:02:38,400 construye consultas complejas y luego usa la base de datos solo como un almacén. 19 00:02:38,560 --> 00:02:41,960 Mientras que en el segundo modelo parte de esa lógica se traslada al servidor, 20 00:02:42,479 --> 00:02:47,099 la aplicación llama a rutinas ya preparadas y la base de datos las procesa directamente. 21 00:02:47,099 --> 00:03:03,819 Entonces, esta diapositiva enfrenta dos filosofías. En la primera, toda la inteligencia en la aplicación está en la aplicación y la base de datos solo guarda datos. Y en la segunda parte de esa inteligencia se mueve el motor de la base de datos mediante procedimientos almacenados. 22 00:03:03,819 --> 00:03:11,500 El resultado es una aplicación más ligera y una base de datos capaz de ejecutar su lógica propia. 23 00:03:12,599 --> 00:03:16,900 Ventaja, el primer enfoque, la lógica está centralizada en el código de la aplicación, 24 00:03:17,479 --> 00:03:20,800 a veces más difícil de versionar para equipos de desarrollo. 25 00:03:21,360 --> 00:03:25,159 Y la segunda, tenemos que es un enfoque que se reduce en la duplicidad 26 00:03:25,159 --> 00:03:27,840 y se encapsulan reglas importantes cerca de los datos. 27 00:03:28,580 --> 00:03:30,919 Imaginemos una empresa con tres aplicaciones distintas, 28 00:03:30,919 --> 00:03:33,340 una web, una aplicación móvil y un sistema interno. 29 00:03:33,340 --> 00:03:45,259 Si las tres tienen que calcular el mismo descuento y lo hacen cada una por su cuenta, puede haber errores o inconsistencias. Si ese cálculo está en un procedimiento almacenado, las tres aplicaciones usan exactamente la misma lógica. 30 00:03:46,639 --> 00:03:58,860 Entonces, mover la lógica al motor permite desacoplar parte del procedimiento de la capa cliente y acercarlo al dato, que es donde realmente ocurre la operación. 31 00:03:58,860 --> 00:04:09,439 Aquí descomponemos lo que es un procedimiento almacenado en el que aparecen las distintas partes del mismo. 32 00:04:09,439 --> 00:04:20,800 En la primera tenemos la declaración de la rutina, que sería esta de aquí, en el que se comienza con Create, Procedure y luego el nombre del procedimiento. 33 00:04:21,420 --> 00:04:25,819 Este va a llevar parámetros de entrada y salida. 34 00:04:25,819 --> 00:04:35,860 Veis que aquí los paréntesis sí tienen que aparecer, pero que los parámetros, al ponerlos entre corchetes, serían parámetros en el que son opcionales. 35 00:04:36,319 --> 00:04:43,639 Entonces, aquí entrarían las variables de entrada y las variables de salida, como si fuera un método, una función o un procedimiento. 36 00:04:43,759 --> 00:04:45,379 Bueno, aquí sería un procedimiento en este caso. 37 00:04:46,980 --> 00:04:53,519 También tiene una serie de características que también son opcionales, en el que vemos el comportamiento determinista, veremos más adelante qué es. 38 00:04:53,519 --> 00:04:58,639 y luego el cuerpo de la rutina, que es donde están las sentencias SQL válidas. 39 00:04:59,740 --> 00:05:06,579 Además, aquí nos aparece el requisito de qué versión de MySQL necesitamos para que esto funcione. 40 00:05:07,019 --> 00:05:12,279 Pero un procedimiento almacenado es una rutina guardada dentro de la base de datos que contiene instrucciones SQL 41 00:05:12,279 --> 00:05:16,680 y que luego puede invocarse por un nombre, como una llamada a una función o un procedimiento. 42 00:05:17,100 --> 00:05:21,220 Es como una función o bloque de instrucciones reutilizable, pero almacenado en el servidor de la base de datos. 43 00:05:22,100 --> 00:05:43,660 Aquí vemos la estructura general de un procedimiento almacenado. Primero se declara el nombre, después se definen sus parámetros, si los tiene, luego pueden indicarse ciertas características de comportamiento y finalmente se escribe el bloque de instrucciones SQL que ejecutará, en otras palabras, es una rutina que queda guardada en la base de datos y que puede reutilizarse todas las veces que se haga falta. 44 00:05:43,660 --> 00:05:51,079 El nombre del procedimiento identifica la rutina, convierte que sea descriptivo 45 00:05:51,079 --> 00:05:56,300 Por ejemplo, podemos llamarle calcular comisión, insertar cliente, obtener facturas pendientes, etc. 46 00:05:56,839 --> 00:06:00,040 Los parámetros permiten enviar datos al procedimiento o recibir resultados 47 00:06:00,040 --> 00:06:04,699 Y características sirven para describir propiedades de la rutina 48 00:06:04,699 --> 00:06:08,939 En una explicación oral no hace falta profundizar demasiado aquí 49 00:06:08,939 --> 00:06:15,360 pero sí decir que algunas opciones especifican cómo se comporta o qué tipo de operaciones va a realizar. 50 00:06:15,779 --> 00:06:19,959 El cuerpo es la lógica real, es donde están las consultas, validaciones, asignaciones, condiciones, etc. 51 00:06:20,240 --> 00:06:25,939 Un ejemplo sencillo, por ejemplo, sería un procedimiento llamado obtener empleados por departamento, 52 00:06:26,379 --> 00:06:30,720 en el que recibe el ID de un departamento y devuelve todos los empleadores de ese departamento. 53 00:06:30,860 --> 00:06:36,139 En vez de escribir siempre la misma consulta, desde la aplicación se centraliza en la base de datos. 54 00:06:36,139 --> 00:06:57,060 Un ejemplo sería, pues, create procedure, listar productos, abre paréntesis, cierra paréntesis, y luego dentro del mismo procedimiento aparecerían todas las instrucciones SQL. Por ejemplo, select asterisco from productos. Es un ejemplo simple, pero nos da una idea de que podemos guardar una consulta bajo un nombre y luego reutilizarla cuando queramos. 55 00:06:57,060 --> 00:07:10,810 En cuanto a la comparación de procedimientos, aquí tenemos sin procedimientos almacenados y con procedimientos almacenados para que veáis la diferencia 56 00:07:10,810 --> 00:07:17,750 Sin procedimiento almacenado que tenemos muchas secuencias, muchas sentencias SQL complejas que viajan entre la aplicación y el servidor 57 00:07:17,750 --> 00:07:23,709 Se satura más la red, hay más ida y vuelta de instrucciones, mientras que en el procedimiento almacenado que tenemos aquí abajo 58 00:07:23,709 --> 00:07:41,569 Solo se envía una llamada breve con la llamada con call, se llamaría al procedimiento y le llama por su nombre, con nombre guión bajo SP entre paréntesis. ¿Por qué? Porque no tiene ningún parámetro de entrada. El procesamiento, recordad que siempre los paréntesis hay que ponerlos por defecto. 59 00:07:41,569 --> 00:08:00,730 El procesamiento ocurre en el servidor y se minimiza, lógicamente veis, el tráfico. La adquisitiva destaca que los procedimientos almacenados pueden reducir el tráfico de red porque en vez de mandar grandes consultas o múltiples operaciones desde la aplicación, solo se manda una orden corta para que el servidor haga el resto. 60 00:08:00,730 --> 00:08:16,910 Se observa una ventaja importante, la reducción del tráfico de red. Si la aplicación necesita ejecutar muchas sentencias complejas, cada una de ellas tiene que enviarse al servidor. En cambio, con procedimientos almacenados basta con mandar una llamada corta y dejar que el motor realice internamente todo el trabajo. 61 00:08:16,910 --> 00:08:25,670 No siempre es mejor el rendimiento, será enorme en todos los casos 62 00:08:25,670 --> 00:08:30,689 pero sí hay ventajas claras cuando tenemos que hay muchas operaciones encadenadas 63 00:08:30,689 --> 00:08:34,549 la lógica es repetitiva o el sistema trabaja con muchas peticiones 64 00:08:34,549 --> 00:08:39,250 Pensemos en un cierre mensual sin procedimientos almacenados 65 00:08:39,250 --> 00:08:42,809 la aplicación podría enviar una consulta para ventas, otra para comisiones 66 00:08:42,809 --> 00:08:45,710 y otra para actualizar estados y otra para auditoría 67 00:08:45,710 --> 00:08:57,590 Con un procedimiento almacenado, todo eso puede quedar dentro de una sola rutina y la aplicación solo ejecutará el call, cierre mensual, entre paréntesis, punto y coma. 68 00:08:58,129 --> 00:09:03,649 ¿Veis la diferencia y la sencillez con el hecho de tener un procedimiento almacenado? 69 00:09:11,250 --> 00:09:14,889 Hablamos de los parámetros. Aquí se explican los tres tipos de parámetros que puede haber. 70 00:09:14,889 --> 00:09:39,950 El IN será valores de entrada que ingresan para ser procesados. El OUT será, veis aquí que ha llamado al procedimiento P2 metiendo un parámetro que es este número entero. El OUT sería el resultado que devuelve el procedimiento. Variables que ya no solo, ahora ya no entra un parámetro sino que va a devolver un parámetro y se devuelve a través de esta arroba Y. 71 00:09:39,950 --> 00:10:01,190 Esto va a hacer que luego se devuelva en esta otra a través del select. En cuanto al in-out es cuando entra con un común valor y lo modifica y sale cambiado. Como tanto, el in sirve para pasar datos al procedimiento. El procedimiento los usa, pero no los devuelve modificados como salida formal. 72 00:10:02,190 --> 00:10:03,830 Es el call que tenemos aquí. 73 00:10:04,570 --> 00:10:07,789 Aquí 1, 2, 3, 4, 5 entra para ser procesado. 74 00:10:08,190 --> 00:10:10,929 En cambio, en el out sirve para devolver un resultado al exterior. 75 00:10:10,929 --> 00:10:19,409 La aplicación o la sesión SQL recibe el valor generado, que sería este de aquí. 76 00:10:19,929 --> 00:10:23,350 Y una vez que lo recibe, tenemos que lo devuelve. 77 00:10:23,450 --> 00:10:26,590 Aquí lo ha utilizado y con él se le devuelve menos 5. 78 00:10:27,450 --> 00:10:33,950 El último sería el in-out, que sería el parámetro que llega con un valor inicial y luego se devuelve, se transforma y lo devuelve de nuevo. 79 00:10:35,590 --> 00:10:38,870 Los parámetros son la forma en la que un procedimiento se comunica con el exterior. 80 00:10:39,129 --> 00:10:45,649 Los parámetros in introducen datos, los out devuelven resultados y los in-out hacen que las dos cosas se produzcan a la vez, 81 00:10:45,649 --> 00:10:49,409 porque reciben un valor, lo procesan y luego lo devuelven modificado. 82 00:10:49,409 --> 00:11:11,990 Un ejemplo de IN, si tengo un procedimiento llamado buscar cliente, por ejemplo, en el que dentro del mismo hemos metido el ID cliente como un valor entero, se pondría como IN de ser un valor que se va a ingresar, ID cliente es el nombre del parámetro y luego IN que sería el tipo de, eso aparecería entre paréntesis en el procedimiento. 83 00:11:11,990 --> 00:11:29,929 El identificador del cliente entra al procedimiento para localizar sus datos. En el out, si tengo, por ejemplo, contar pedidos, podemos poner dentro de entre paréntesis out total in, que sería out porque es un parámetro de salida, por total sería el nombre del parámetro e in sería porque es un entero. 84 00:11:29,929 --> 00:11:33,929 El procedimiento calcula el número de pedidos y lo guarda en una variable de salida. 85 00:11:35,269 --> 00:11:39,889 Y el in-out, supongamos un procedimiento que recibe un saldo provisional y le añade un bonus. 86 00:11:40,250 --> 00:11:43,710 Entonces el valor entra con una cantidad inicial y sale con otra distinta. 87 00:11:44,230 --> 00:11:46,009 Podemos imaginarlo como una caja. 88 00:11:46,549 --> 00:11:52,809 In mete información dentro, out saca información fuera e in-out mete algo, lo transforma dentro y lo devuelve. 89 00:11:55,970 --> 00:12:00,590 Por tanto, los pasos en la construcción y ejecución de lo que estamos hablando serían estos cuatro. 90 00:12:00,590 --> 00:12:22,870 En un principio preparamos, creamos y seleccionamos la base de datos. Después la estructura en la que creamos una tabla e insertamos datos dentro de la misma. El paso tercero sería la declaración del procedimiento. Hemos creado el procedimiento llamado P1 sin parámetros ni de entrada ni de salida ni de entrada a salida y las sentencias SQL lo único que hace es un select desde la tabla D. 91 00:12:23,710 --> 00:12:28,029 Por último, llamamos para ejecutar dicho procedimiento almacenado a través de call, 92 00:12:28,330 --> 00:12:32,669 llamando al nombre de la función sin parámetros y nos devolvería esto que aparece aquí. 93 00:12:34,950 --> 00:12:40,289 Esta diapositiva no se centra solo en la sintaxis, sino en el flujo mental correcto al trabajar con procedimientos. 94 00:12:40,289 --> 00:12:45,289 Primero preparo el entorno, luego creo la estructura de datos, después defino la rutina y por último la ejecuto. 95 00:12:46,149 --> 00:12:50,570 Aquí vemos que trabajar con procedimientos no consiste solo en escribir un create procedure. 96 00:12:50,570 --> 00:12:56,250 dure. Antes hay que preparar el contexto, seleccionar la base de datos correcta, crear tablas y datos de 97 00:12:56,250 --> 00:13:01,450 ejemplo. Solo entonces se declara el procedimiento y finalmente se ejecuta con call. Un ejemplo sería 98 00:13:01,450 --> 00:13:07,070 si quiero crear un procedimiento que devuelva todos los productos caros, antes necesito que 99 00:13:07,070 --> 00:13:12,950 exista una tabla de productos y que tenga registros. No tendría sentido definir la rutina 100 00:13:12,950 --> 00:13:18,090 sobre una tabla que todavía no está creada. Por tanto, este esquema refleja una metodología muy 101 00:13:18,090 --> 00:13:22,850 útil, primero se construye el escenario, luego se define la lógica y finalmente se prueba. Es 102 00:13:22,850 --> 00:13:27,909 parecido a programar una función, antes de usarla necesitamos que existan las variables y las 103 00:13:27,909 --> 00:13:39,899 estructuras con las que vamos a trabajar. Aquí en esta nueva diapositiva hablamos del uso del 104 00:13:39,899 --> 00:13:47,179 delimiter para agrupar la lógica compleja con bloques begin, end. A la izquierda aparece el 105 00:13:47,179 --> 00:13:54,740 problema, que sería si no cambiamos el delimitador, MySQL puede interpretar el punto y coma como final 106 00:13:54,740 --> 00:13:59,919 prematura del comando. Entonces, y el procedimiento no se crea correctamente. Aquí lo tenemos, tenemos 107 00:13:59,919 --> 00:14:05,860 el create procedure simple proc con un parámetro dentro de la salida. ¿Veis cómo lo pone? Pone qué 108 00:14:05,860 --> 00:14:12,840 tipo de parámetro es, in, out o in out. Aquí es uno de salida. ¿Qué nombre tiene el parámetro? Le llama 109 00:14:12,840 --> 00:14:25,799 parámetro 1 y luego qué tipo de parámetro va a ser, que es un valor entero. Después mete el begin y aparecería al final el end. Si veis aquí, si no ponemos el proceduré 110 00:14:25,799 --> 00:14:39,450 aquí nos está dando, aquí terminaría de manera, generaría un error porque terminaría de manera prematural no poner el delimiter. Entonces, si veis aquí a la derecha, 111 00:14:39,450 --> 00:14:55,710 Tenemos la solución, cambiar temporalmente el delimitador, por ejemplo, con dos barras. Hemos definido el delimitador con esas dos barras para indicar que tiene que leer todo el procedimiento. El procedimiento desde que empieza hasta que finaliza para que no finaliza de manera prematura en la primera sentencia que encuentra. 112 00:14:56,309 --> 00:14:58,389 Definir todo el procedimiento, cerrar con el end 113 00:14:58,389 --> 00:15:02,190 y posteriormente poner el delimitador que hemos definido al principio. 114 00:15:02,629 --> 00:15:05,149 Y luego restaurar el delimiter a punto y coma 115 00:15:05,149 --> 00:15:09,970 para que pueda ser utilizado en las siguientes sentencias SQL. 116 00:15:10,690 --> 00:15:14,549 El cliente MySQL normalmente entiende punto y coma como fin de instrucción, 117 00:15:15,169 --> 00:15:17,649 pero dentro de un procedimiento queremos poner muchas sentencias 118 00:15:17,649 --> 00:15:21,049 terminadas en punto y coma y no queremos que terminen de manera prematura, 119 00:15:21,190 --> 00:15:22,389 como aquí generando este error. 120 00:15:22,970 --> 00:15:24,570 Entonces, si no cambiamos el delimitador, 121 00:15:24,570 --> 00:15:29,090 el cliente cree que la institución terminó antes de tiempo, por eso se cambia a otro símbolo temporalmente. 122 00:15:29,629 --> 00:15:34,769 Esta es una parte muy importante de MySQL, cuando un procedimiento tiene varias sentencias dentro de un bloque, 123 00:15:35,110 --> 00:15:39,389 veis que tiene un bloque que empieza aquí con el begin y un bloque que termina con el end. 124 00:15:40,529 --> 00:15:47,009 Cada una suele acabar en un punto y coma, el problema es que el cliente MySQL también usa ese símbolo 125 00:15:47,009 --> 00:15:52,730 para decidir cuándo ha terminado un comando completo, por eso cambiamos temporalmente el delimitador, 126 00:15:52,730 --> 00:15:54,990 por ejemplo con barra a barra, podéis poner otro 127 00:15:54,990 --> 00:15:57,210 para que todo el bloque llegue 128 00:15:57,210 --> 00:15:59,370 entero al servidor, lea todo ese bloque 129 00:15:59,370 --> 00:16:00,850 ...