11-Stored Procedures
11-Stored Procedures
Semestre: 4
Docente: José Palacio
Asignatura: Desarrollo de Aplicaciones con Acceso a Datos
Tema: Procedimientos Almacenados
PROCEDIMIENTOS ALMACENADOS
INTRODUCCIÓN
En la actualidad los SGBD son más que simples repositorios de datos que permiten controlar la
integridad de los datos; estos sistemas incluyen rutinas que permiten automatizar procesos, lo que
permite que en el SGBD puedan desarrollarse pequeñas aplicaciones o rutinas de código, un ejemplo
de estos son los triggers, que se vieron en el tutorial anterior.
Otras posibles rutinas en las bases de datos son los procedimientos y funciones almacenadas, los
cuales a diferencia de los triggers no se ejecutan automáticamente, deben ser invocados a través
de una instrucción SQL. Tanto las funciones como los procedimientos almacenados representan un
conjunto de instrucciones SQL almacenados bajo un nombre, por ejemplo se puede definir una
instrucción como SELECT dentro de un procedimiento almacenado, para luego ejecutarla cada vez
que sea necesarios, simplemente invocando el procedimiento por su nombre y si el procedimiento
lo requiere, se pueden recibir parámetros que definan la consulta a ejecutar.
Tanto los procedimientos como las funciones almacenadas pueden ser llamados desde aplicaciones
externas a través de los middlewares respectivos, como por ejemplo desde una aplicación Java a
través del JDBC, en este caso a través de la clase CallableStatement.
El uso de procedimientos y funciones almacenadas a través de las aplicaciones, le introducen
seguridad al acceso a los datos, ya que no es necesario conocer la estructura de la base de datos
para poderlos utilizar, simplemente se llama al procedimiento o función y se le envían los
parámetros necesarios.
DESCRIPCIÓN DE LA SINTAXIS
LENGUAJE DE PROGRAMACIÓN
La sintaxis utilizada en la redacción del documento para el lenguaje de programación es la siguiente:
1. El lenguaje de programación Java es de tipo Case Sensitive, por lo tanto diferencia
mayúsculas de minúsculas.
2. Se utilizará el estilo de escritura CamelCase, para la identificación de los elementos del
programa.
a. Para nombres de clases y constructores se utilizará UpperCamelCase, por ejemplo:
ClasePrincipal.
b. Para las constantes se utilizará UPPERCASE, por ejemplo: VALORPI.
c. Para el resto de elementos se utilizará lowerCamelCase, por ejemplo:
primerNombre.
3. Los textos escritos en negrita, con un color distinto al negro representan palabras
reservadas del lenguaje y deben ser escritos tal cual aparecen en el documento.
Los textos escritos en cursiva representan valores que deberán ser reemplazados por el valor
indicado en el documento, por lo general un nombre definido por el programador.
PROCEDIMIENTOS ALMACENADOS
Los procedimientos almacenados (stored procedures) son uno de los diferentes tipos de rutinas
almacenadas que puede ser gestionada desde un SGBD de tipo SQL, y MySQL no es la excepción.
Los procedimientos almacenados permiten identificar un conjunto de instrucciones SQL bajo un
nombre y de esta forma similar su ejecución, ya que bastaría simplemente con llamar al
procedimiento almacenado y enviarle los parámetros respectivos en caso de ser necesarios.
Los procedimientos almacenados en MySQL requieren de la existencia de la tabla proc en la base
de datos mysql. Esta tabla se crea durante el proceso de instalación de MySQL. Para la creación de
un procedimiento almacenado se requiere tener permisos para CREATE ROUTINE.
mysql> DELIMITER ;
mysql> CALL proc(@cuenta);
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT @cuenta;
+------+
| @a |
+------+
| 3 |
+------+
1 row in set (0.00 sec)
Si se define la cláusula SQL SECURITY en modo INVOKER, se trabajará con los privilegios del usuario
que invoca y no el definido en la cláusula DEFINER.
CREATE DEFINER = 'admin'@'localhost' PROCEDURE cuentas()
SQL SECURITY INVOKER
BEGIN
SELECT 'Número de Cuentas:', COUNT(*) FROM mysql.user;
END;
INTERFAZ CALLABLESTATEMENT
La interfaz CallableStatement permite ejecutar procedimientos almacenados de SGBD tipo SQL. La
API de JDBC proporciona una sintaxis estándar para los llamados a procedimientos almacenados de
diferentes SGBD, por lo que el llamado siempre será el mismo, sin importar el servidor.
La sintaxis tiene una forma de incluir un parámetro de resultado y uno que no. Si se usa el parámetro
de resultado, este debe registrarse como parámetro tipo OUT, los otros parámetros pueden ser de
tipo IN, OUT o INOUT. Los parámetros se referencian secuencialmente iniciando desde 1.
Los parámetros tipo IN se establecen utilizando los mismos métodos definidos para la interfaz
PreparedStatement( setString(), setInt(), etc.) ya que lo heredan de esta interfaz. Los tipos de datos
para los parámetros OUT, deben establecerse antes de llamar al procedimiento y sus valores,
pueden recuperarse con los métodos get respectivos de cada tipo.
Los objetos de tipo CallableStatement, pueden devolver uno o varios objetos de tipo ResultSet, los
cuales pueden ser procesados utilizando los métodos heredados de Statement.
Se puede definir el parámetro con el índice (iniciando desde 1) o el nombre del parámetro.
Para los parámetros tipo OUT o INOUT, se debe especificar el tipo de dato de los mismo antes de
ejecutar el llamado definiendo el método registerOutParameter() de la interfaz CallableStatement.
Para la definición de los tipos de datos se hace uso de la clase Types del paquete java.sql. La cual
incluye un conjunto de constantes estáticas asociadas a los tipos de datos basados en SQL.
import java.sql.Types;
...
llamada.registerOutParameter(2, Types.INTEGER);
llamada.registerOutParameter("parametroOut", Types.VARCHAR);
Al igual que con los métodos set se puede definir el índice del parámetro o el nombre.
A través del método getResultSet() del objeto CallableStatement, se puede obtener el ResultSet
resultado del procedimiento. En caso de que el procedimiento devuelva más de un ResultSet, se
puede hacer uso del método getMoreResults() del boolean resultado, para obtener dichos
ResultSet.
while (resultado){
ResultSet rs = llamada.getResultSet();
...
resultado = llamada.getMoreResults();
}
Con los métodos get respectivos se obtienen los valores de los parámetros OUT o INOUT.
int valorSalida = llamada.getInt(2); // basado en el índice
int valorSalida = llamada.getInt("parametroOut"); // basado en nombre
Se procede a crear las clases en Java que harán uso de los procedimientos almacenados:
import java.sql.Connection;
import java.sql.CallableStatement;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.ArrayList;
Sólo queda construir la clase que contenga el main que haga uso de la clase datos para llamar a los
procedimientos almacenados, teniendo en cuenta los tipos de retorno de los métodos definidos en
la clase.
Para el método llamarInsertar(), se debe utilizar un int, para el método llamarBuscar(), se devolverá
un ArrayList de String y para el método llamarContar(), se recibirá e resultado en una variables de
tipo int.