0% encontró este documento útil (0 votos)
60 vistas10 páginas

11-Stored Procedures

El documento describe los procedimientos almacenados en MySQL. Los procedimientos almacenados permiten agrupar instrucciones SQL bajo un nombre para ejecutarlas de forma repetida. Se crean usando la instrucción CREATE PROCEDURE y pueden recibir parámetros. También se especifica la sintaxis para crear un procedimiento almacenado en MySQL y las características que se pueden definir como el tipo de parámetro, comentarios y seguridad.

Cargado por

josepalacio497
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
60 vistas10 páginas

11-Stored Procedures

El documento describe los procedimientos almacenados en MySQL. Los procedimientos almacenados permiten agrupar instrucciones SQL bajo un nombre para ejecutarlas de forma repetida. Se crean usando la instrucción CREATE PROCEDURE y pueden recibir parámetros. También se especifica la sintaxis para crear un procedimiento almacenado en MySQL y las características que se pueden definir como el tipo de parámetro, comentarios y seguridad.

Cargado por

josepalacio497
Derechos de autor
© © All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
Está en la página 1/ 10

Programa: Técnico Profesional en Programación de Computadores

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

SISTEMA DE GESTION DE BASE DE DATOS


La sintaxis utilizada en la redacción del documento en cuanto al SGBD MySQL es la siguiente:
1. Los textos escritos en mayúscula sostenida se escriben tal y como se muestran en la sintaxis
(no es obligatorio escribirlos en mayúscula, MySQL no es Case Sensitive).
2. Los textos escritos en minúscula y cursiva representan valores que deberán ser
reemplazados por el valor indicado en el documento, por lo general un nombre definido por
el usuario.
3. Los textos escritos entre corchetes ([ ]) son opcionales, pueden escribirse o no, todo

JOSE PALACIO VELASQUEZ Página 1


depende de los requerimientos.
4. Los textos escritos entre llaves ({ }) indican que de un conjunto de valores se debe escoger
solamente uno, por lo general los valores se separan por el carácter pipe (|).
5. El carácter Pipe (|) representa el conector lógico o, si se encierra entre corchetes es un o
exclusivo.
6. Todo comando MySQL debe terminar en punto y coma (;).
7. Los caracteres corchetes ([ ]), llaves ({ }) y pipe (|), no deben escribirse.

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.

CREACIÓN DE UN PROCEDIMIENTO ALMACENADO EN MYSQL


Para la creación de un procedimiento almacenado, se hace uso de la instrucción CREATE
PROCEDURE, según la siguiente sintaxis.
CREATE
[DEFINER = { usuario | CURRENT_USER }]
PROCEDURE nombre_proc ([parámetro[,...]])
[características ...] cuerpo_procedimiento

JOSE PALACIO VELASQUEZ Página 2


La instrucción empieza con la palabra reservada CREATE, que permitirá crear el procedimiento
almacenado con el nombre indicado más adelante en nombre_proc.
Las cláusulas DEFINER especifica el contexto de seguridad que se utilizará para verificar los permisos
de acceso durante la invocación del procedimiento. Esto quiere decir que sin importar que usuario
invoque el procedimiento, este se ejecutará con los privilegios del usuario definido. Si no se
especifica la cláusula DEFINER, la cuenta por defecto es la del usuario que llame al procedimiento,
esto es lo mismo que decir DEFINER = CURRENT_USER.
PROCEDURE define el nombre del procedimiento (nombre_proc).
Los procedimientos pueden contener parámetros, que pueden ser de diferentes tipos, tenga o no
parámetros los paréntesis son obligatorios para el nombre del procedimiento. Los tipos de
parámetros no hacen referencia al tipo de dato del parámetro, aunque este también debe ser
definido, se refiere a si los parámetros son de tipo:
 IN: Este tipo de parámetro introduce un valor para ser utilizado en el procedimiento.
 OUT: Es un parámetro que devolverá un valor calculado en el procedimiento al llamador del
mismo. Inicialmente el valor de este parámetro es null, y el valor es mostrado al llamador
cuando el procedimiento termina.
 INOUT: Estos parámetros son inicializados y pueden ser modificados en el procedimiento,
de tal forma que cualquier cambio es visible para el llamador cuando finaliza el
procedimiento.
Luego de definir el tipo de parámetro se debe definir el nombre del parámetro y luego el tipo de
dato del mismo, el cual puede ser cualquier tipo de dato de MySQL. Por ejemplo:
IN nombre VARCHAR(50)

Si se requieren varios parámetros estos se deben separar por comas (,).


Las características definidas en la creación del procedimiento pueden ser las siguientes:
COMMENT 'string'
| LANGUAGE SQL
| [NOT] DETERMINISTIC
| { CONTAINS SQL | NO SQL | READS SQL DATA | MODIFIES SQL DATA }
| SQL SECURITY { DEFINER | INVOKER }

 COMMENT: Permite definir un comentario para el procedimiento almacenado


 LANGUAGE: Indica en que lenguaje se encuentra escrita la rutina, se mantiene para
compatibilidad con otros sistemas ya que esta sólo soporta lenguaje SQL.
 [NOT] DETERMINISTIC: Especifica si el procedimiento será de tipo determinista o no
determinista, los procedimientos deterministas siempre devuelven el mismo resultado
cuando se invocan con los mismos valores de entrada, en caso de contrario será no
determinista, por defecto los procedimientos son no deterministas. Aunque esto es más
utilizado en las funciones almacenadas y funciones propias de MySQL. Funciones como
NOW() y RAND() son no deterministas, ya que arrojan resultados diferentes cada vez que
son llamadas, aunque si invocamos RAND con un valor de semilla específico por ejemplo
RAND(5), se vuelve determinista y siempre arroja el mismo resultado.

JOSE PALACIO VELASQUEZ Página 3


 Las características siguientes proporcionan información sobre la naturaleza del uso de datos
por el procedimiento. En MySQL, estas características son solo de asesoramiento. El servidor
no las utiliza para restringir los tipos de declaraciones que se permitirá ejecutar en un
procedimiento.
o CONTAINS SQL: Indica si el procedimiento no contiene instrucciones que lean o
escriban datos, por ejemplo el uso de la instrucción SET para asignar valor a una
variable SET @valor = 1, esta instrucción se ejecuta, pero no lee ni escribe datos en
la base de datos. Si no se define ninguna instrucción de este tipo, este será el valor
predeterminado.
o NO SQL: Indica que el procedimiento contiene instrucciones no SQL.
o READS SQL DATA: Se utiliza para indicar que el procedimiento contiene
instrucciones que leen datos, por ejemplo SELECT, pero no instrucciones que
escriben datos.
o MODIFIES SQL DATA: Indica que el procedimiento contiene instrucciones que
escriben datos en la base de datos
 A través del atributo DEFINER se especifican los privilegios con los que se va a ejecutar el
procedimiento almacenado, esto siempre y cuando en la cláusula SQL SECURITY, se haya
declarado el valor DEFINER. Esto quiere decir que sin importar que usuario invoque el
procedimiento, este se ejecutará con los privilegios del usuario definido. Si la cláusula SQL
SECURITY, se declara de tipo INVOKER, se aplicarán los privilegios del usuario que invoque
el procedimiento, sin importar que indique la cláusula DEFINER. Si no se especifica la
cláusula DEFINER, la cuenta por defecto es la del usuario que invoca el procedimiento, esto
es lo mismo que decir DEFINER = CURRENT_USER.

LLAMAR A UN PROCEDIMIENTO ALMACENADO


Para realizar un llamado a un procedimiento almacenado simplemente se hace uso de la instrucción
CALL, de la siguiente manera:
CALL nombre_proc([parámetro[,...]])

Un ejemplo de la creación de un procedimiento almacenado y su respectivo llamado sería:


mysql> DELIMITER //
mysql> CREATE PROCEDURE proc (OUT param INT)
-> BEGIN
-> SELECT COUNT(*) INTO param FROM clientes;
-> END//
Query OK, 0 rows affected (0.01 sec)

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)

JOSE PALACIO VELASQUEZ Página 4


En el ejemplo se observa la creación del procedimiento almacenado proc, el cual recibe un
parámetro de salida (OUT) llamado param, internamente el procedimiento realiza un conteo de
todos los registros contenidos en la tabla clientes y almacena el resultado dentro del parámetro de
salida.
Durante el llamado al procedimiento se define que el parámetro de salida será almacenado en la
variable @cuenta, luego se ejecuta un SELECT sobre dicha variable y se observa el resultado de la
ejecución del procedimiento.
En el siguiente ejemplo se hace uso de la instrucción DEFINER, para indicar que el procedimiento se
ejecutará con los privilegios del usuario admin@localhost.
CREATE DEFINER = 'admin'@'localhost' PROCEDURE cuentas()
BEGIN
SELECT 'Número de Cuentas:', COUNT(*) FROM mysql.user;
END;

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;

PROCEDIMIENTOS ALMACENADOS DESDE JAVA


Así como desde una aplicación Java se puede ejecutar una consulta a una base de datos, utilizando
las consultas convencionales, también se puede llamar a ejecutar un procedimiento almacenado, la
diferencia fundamental es que mientras para las primeras se puede utilizar objetos de tipo
Statement y PreparedStatement, para los procedimientos almacenados se utiliza
CallableStatement.

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.

JOSE PALACIO VELASQUEZ Página 5


Se debe tener en cuenta que el uso de estos métodos puede generar excepciones de tipo
SQLException, por lo tanto se debe encerrar su ejecución en un bloque try … catch o implementarlos
directamente con la instrucción throws en la declaración del método.

LLAMAR A UN PROCEDIMIENTO ALMACENADO DESDE JAVA


Los pasos para llamar a un procedimiento almacenado desde Java son los siguientes:

CREAR UN OBJETO TIPO CALLABLESTATEMENT


Lo primero que se debe hacer para llamar a un procedimiento almacenado es crear un objeto de
tipo CallableStatement, para lo cual se debe importar la interfaz del paquete java.sql, luego a través
del método prepareCall del objeto Connection, el cual devuelve un objeto tipo CallableStatement.
import java.sql.CallableStatement;
...
CallableStatement llamada = conn.prepareCall("{call nombre_proc([?[, ...])}");

Se crea un objeto llamada basado en la llamada al procedimiento almacenado nombre_proc, desde


el objeto conn. El manejo de los parámetros del procedimiento es similar al llamado de los valores
de la consulta en un PreparedStatement.
El llamado a prepareCall() consume muchos recursos, debido a la recuperación de los metadatos
que se realizan para los parámetros de salida, por lo tanto se debe minimizar las llamadas a dicho
método.

REGISTRAR LOS PARÁMETROS DEL PROCEDIMIENTO


Luego de creado el objeto CallableStatement se procede a registrar los parámetros. Para los
parámetros tipo IN se utilizan los métodos set heredados de PreparedStatement.
llamada.setString(1, "valor");
llamada.setString("parámetroIn", "valor");

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.

EJECUTAR EL PROCEDIMIENTO ALMACENADO


El siguiente paso consiste en ejecutar el procedimiento almacenado y recibir cualquier ResultSet o
parámetro de salida generado.
Aunque CallableStatement permite la ejecución de cualquier método de ejecución heredado
PreparedStatement, ya sea execute(), executeQuery() o executeUpdate(), se recomienda utilizar

JOSE PALACIO VELASQUEZ Página 6


execute(), ya que es el método más flexible y no requiere saber de antemano si el procedimiento
almacenado retorna algún ResultSet. El método execute() devuelve un verdadero si el primer
resultado obtenido es un objeto ResultSet y falso si el resultado es un conteo de registros afectados
(entero) o no hay un ResultSet, executeQuery() devuelve un ResultSet y executeUpdate() devuelve
un int con el conteo de registros afectados.
boolean resultado = llamada.execute();

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

EJEMPLO DE USO DE UN PROCEDIMIENTO ALMACENADO


En el siguiente ejemplo se creará tres procedimientos almacenados uno para insertar registros en
la tabla clientes u otro para realizar una consulta a dicha tabla y otro para obtener la cantidad de
registros de la tabla.
Se inicia creando la tabla clientes:
TABLA: CLIENTES
CAMPO TIPO TAM PK NULL DESCRIPCION
codigo Int X Código del Cliente (corresponde a la cédula)
nombres Varchar 50 Nombres del Cliente
apellidos Varchar 50 Apellidos del Cliente
direccion Varchar 25 Dirección de Residencia del Cliente
telefono Varchar 10 X Número de Teléfono Fijo o Celular del Cliente

mysql> CREATE TABLE clientes (


codigo INT PRIMARY KEY,
nombres VARCHAR(50) NOT NULL,
apellidos VARCHAR(50) NOT NULL,
dirección VARCHAR(25) NOT NULL,
teléfono VARCHAR(10));
Query OK, 0 rows affected (0.02 sec)

Se crea el procedimiento almacenado que insertara nuevos registros:


mysql> DELIMITER //
mysql> CREATE PROCEDURE ins_cliente (
IN cod INT, IN nom VARCHAR(50), IN ape VARCHAR(50),
IN dir VARCHAR(25), IN tel VARCHAR(10))
BEGIN
INSERT INTO clientes VALUES (cod, nom, ape, dir, tel);
END //
Query OK, 0 rows affected (0.03 sec)

JOSE PALACIO VELASQUEZ Página 7


Se crea el procedimiento que busque un cliente por su número de código:
mysql> CREATE PROCEDURE sel_cliente (IN cod INT)
BEGIN
SELECT * FROM clientes WHERE codigo = cod;
END //
Query OK, 0 rows affected (0.02 sec)

Se crea el procedimiento para que cuenta la cantidad de registros de la tabla clientes:


mysql> CREATE PROCEDURE cont_clientes (OUT cant INT)
BEGIN
SELECT COUNT(*) INTO cant FROM clientes;
END //
Query OK, 0 rows affected (0.20 sec)
mysql> DELIMITER ;

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;

public class Datos{


Connection con;
CallableStatement call;
ResultSet rs;

// El constructor de la clase conecta con la base de datos


public Datos(){
try{
con = DriverManager.getConnection("jdbc:mysql://localhost/datos",
"root","Passw0rd");
} catch (SQLException ex){
System.out.println("Error de Conexión");
}
}

// Método que llamará al procedimiento ins_cliente


// Recibe como parámetros los valores a utilizar en el procedimiento
public int llamarInsertar(int cod, String nom, String ape, String dir, String tel){
// Variable que almacenará la cantidad de registros afectados (1 registro)
int resp = 0;
try{
// Se prepara la llamada al procedimiento ins_cliente
call = con.prepareCall("{call ins_cliente(?, ?, ?, ?, ?)}");
// Se preparan los parámetros a enviar
call.setInt(1, cod);
call.setString(2, nom);
call.setString(2, ape);
call.setString(2, dir);
call.setString(2, tel);
// Como la instrucción a ejecutar es un INSERT INTO se ejecuta un executeUpdate()
resp = call.executeUpdate();
} catch (SQLException ex){
// En caso de que se genere una excepción se envía el valor de cero (0)
resp = 0;
}
return resp;
}

JOSE PALACIO VELASQUEZ Página 8


// Método que llamará al procedimiento sel_cliente
// Recibe como parámetros el código del cliente a buscar
public ArrayList<String> llamarBuscar(int cod){
// Variable que almacenará el registro obtenido
ArrayList<String> resultados;
try{
// Se prepara la llamada al procedimiento ins_cliente
call = con.prepareCall("{call sel_cliente(?)}");
// Se preparan los parámetros a enviar
call.setInt(1, cod);
// Se ejecuta el método execute() que devuelve true si se obtiene un ResultSet
if (call.execute()){
// Se recibe el ResultSet y se almacena en el ArrayList resultados
rs = call.getResultSet();
resultados.add(("Código: " + call.getInt(1));
resultados.add(("Nombre: " + call.getString(2));
resultados.add(("Apellido: " + call.getString(3));
resultados.add(("Dirección: " + call.getString(4));
resultados.add(("Teléfono: " + call.getString(5));
}
} catch (SQLException ex){
// En caso de que se genere una excepción se envía el valor de cero (0)
resultados = null;
}
return resultados;
}

// Método que llamará al procedimiento cont_clientes


// Recibe como parámetros los valores a utilizar en el procedimiento
public int llamarContar(){
// Variable que almacenará la cantidad de registros obtenidos
// del parámetro tipo OUT cant
int resp = 0;
try{
// Se prepara la llamada al procedimiento ins_cliente
call = con.prepareCall("{call cont_clientes(?)}");
// Se preparan el parámetro tipo OUT a recibir indicando el tipo de dato
call.registerOutParameter(1, Types.INTEGER);
// Se llama al método execute() el cual devolverá true si se obtiene un
// ResultSet, no se usará el ResultSet, se usará el parámetro cant
if (call.execute()){
// Se obtiene el valor devuelto por el procedimiento
resp = call.getInt(1);
}
} catch (SQLException ex){
// En caso de que se genere una excepción se envía el valor de cero (0)
resp = 0;
}
return resp;
}
}

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.

JOSE PALACIO VELASQUEZ Página 9


BIBLIOGRAFIA
 MySQL 5.7 Reference Guide. Including MySQL NDB Cluster 7.5 and NDB Cluster 7.6.
Recuperado de: https://dev.mysql.com/doc/refman/5.7/en/create-procedure.html
 Oppel, A., & Sheldon, R. (2009). SQL A Beginner ’ s Guide Third Edition. Fortune.
https://doi.org/10.1036/0071548645
 Funciones Deterministas y No Deterministas. Recuperado de:
https://docs.microsoft.com/es-es/sql/relational-databases/user-defined-
functions/deterministic-and-nondeterministic-functions?view=sql-server-2017
 Java Platform, Standard Edition & Java Development Kit Version 9 API Specification –
®

Interface CallableStatement. Recuperado de:


https://docs.oracle.com/javase/9/docs/api/java/sql/CallableStatement.html
 MySQL Connector/J 5.1 Developer Guide: Using JDBC CallableStatements to Execute Stored
Procedures. Recuperado de: https://dev.mysql.com/doc/connector-j/5.1/en/connector-j-
usagenotes-statements-callable.html
 Usando CallableStatements para ejecutar procedimientos almacenados. Recuperado de:
https://www.adictosaltrabajo.com/tutoriales/usando-callable-statements-to-execute-
stored-procedure/

JOSE PALACIO VELASQUEZ Página 10

También podría gustarte