MySQL nos proporciona la capacidad de crear procedimientos almacenados . Los procedimientos almacenados son una parte poderosa de MySQL (y otros sistemas de administración de bases de datos, como SQL Server) y le permiten hacer más que las vistas.
Un procedimiento almacenado es una colección de declaraciones SQL que se almacenan en la base de datos. Un procedimiento almacenado puede contener lógica empresarial, que es uno de los aspectos clave que distingue a los procedimientos almacenados de las vistas. Un procedimiento almacenado puede aceptar parámetros y puede establecer variables, escriba IF
sentencias, etc. dentro de un procedimiento almacenado.
¿Cómo funcionan los procedimientos almacenados?
En primer lugar, crea el procedimiento almacenado. Luego, una vez que se ha creado, puede ejecutarlo (o más precisamente, "llamarlo").
Para ejecutar un procedimiento almacenado, lo "llama". Cuando lo llama, también proporciona los parámetros que pueda requerir. Luego, el procedimiento almacenado se ejecutará, utilizando sus parámetros de la forma que especifique el código.
Por ejemplo, podría escribir un procedimiento almacenado que acepte un FruitId
parámetro. El procedimiento almacenado podría tomar ese parámetro y usarlo para verificar el inventario de esa fruta en particular. Por lo tanto, podría llamar al procedimiento almacenado, cada vez con una ID de fruta diferente y devolvería un valor que le mostraría la cantidad de esa fruta en stock.
Crear un procedimiento almacenado
Los procedimientos almacenados se crean utilizando CREATE PROCEDURE
declaración.
Sintaxis
Esta es la sintaxis para crear un procedimiento almacenado:
CREATE PROCEDURE sp_name(p_1 INT) BEGIN ...code goes here... END;
Reemplazar sp_name con cualquier nombre que le gustaría usar para el procedimiento almacenado. Los paréntesis son obligatorios:encierran cualquier parámetro. Si no se requieren parámetros, los paréntesis pueden estar vacíos.
El cuerpo principal del procedimiento almacenado va entre BEGIN
y END
palabras clave Estas palabras clave se utilizan para escribir sentencias compuestas. Una declaración compuesta puede contener varias declaraciones, y estas se pueden anidar si es necesario. Por lo tanto, puede anidar BEGIN
y END
bloques.
En la mayoría de los casos, también deberá rodear el CREATE PROCEDURE
declaración con DELIMITER
comandos y cambiar END;
a END //
. Así:
DELIMITER // CREATE PROCEDURE sp_name(p_1 INT) BEGIN ...code goes here... END // DELIMITER ;
Explicaré por qué pronto, pero por ahora, veamos un ejemplo.
Ejemplo
Aquí hay un ejemplo simple de cómo crear un procedimiento almacenado. Ejecutando el siguiente código contra nuestro FruitShop base de datos creará un procedimiento almacenado llamado spCheckFruitStock :
DELIMITER // CREATE PROCEDURE spCheckFruitStock(thisFruit SMALLINT) BEGIN SELECT Fruit.FruitName, Fruit.Inventory, Units.UnitName FROM Fruit INNER JOIN Units ON Fruit.UnitId = Units.UnitId WHERE Fruit.FruitId = thisFruit; END // DELIMITER ;
Ahora podemos llamar a ese procedimiento almacenado así:
CALL spCheckFruitStock(1);
Aquí, pasamos un parámetro de 1
cuál es el ID de
Apple
.
Aquí está el resultado:
Podemos hacer lo mismo con cualquier fruta en nuestra base de datos, simplemente cambiando el parámetro pasado al procedimiento almacenado.
Acerca del DELIMITER
Comando
En el ejemplo anterior, agregamos un par de DELIMITER
comandos y reemplazamos un punto y coma con dos barras diagonales. ¿Qué está pasando aquí?
Hicimos esto para decirle a MySQL que use un delimitador diferente mientras crea nuestro procedimiento almacenado.
La razón de esto es que MySQL ya reconoce el punto y coma como un delimitador para marcar el final de cada instrucción SQL. Por lo tanto, tan pronto como MySQL vea el primer punto y coma, interpretará el delimitador como tal y nuestro procedimiento almacenado se rompería.
El DELIMITER
El comando nos permite decirle a MySQL que use un delimitador diferente. En el ejemplo anterior, establecemos esto en dos barras diagonales (//
) pero esto podría haber sido cualquier cosa (aunque, evite usar una barra invertida (\
) ya que ese es el carácter de escape para MySQL). Al cambiar el delimitador, MySQL no intentará interpretar nuestros puntos y comas como el final de la declaración; esperará hasta que vea las dos barras diagonales.
Una vez que hemos creado el procedimiento almacenado, podemos usar DELIMITER ;
para restablecer el delimitador al punto y coma.
Descartar un procedimiento almacenado
Puede descartar un procedimiento almacenado utilizando el DROP PROCEDURE
declaración. Así:
DROP PROCEDURE spCheckFruitStock;
Alteración de un procedimiento almacenado
Puede modificar algunos aspectos de un procedimiento almacenado usando ALTER PROCEDURE
declaración.
Sin embargo, para cambiar el cuerpo del procedimiento almacenado o cualquiera de sus parámetros, debe descartar el procedimiento y volver a crearlo. Así:
DROP PROCEDURE IF EXISTS spCheckFruitStock; DELIMITER // CREATE PROCEDURE spCheckFruitStock(thisFruit SMALLINT) BEGIN SELECT Fruit.FruitId, Fruit.FruitName, Fruit.Inventory, Units.UnitName FROM Fruit INNER JOIN Units ON Fruit.UnitId = Units.UnitId WHERE Fruit.FruitId = thisFruit; END // DELIMITER ;
Aquí, agregamos Fruit.FruitId
a la lista de columnas a devolver.
Resultado:
Un procedimiento almacenado más avanzado
El ejemplo anterior fue simple para demostrar la sintaxis de crear y llamar a procedimientos almacenados. Veamos un procedimiento almacenado un poco más complejo:
DROP PROCEDURE IF EXISTS spCheckFruitStockLevel; DELIMITER // CREATE PROCEDURE spCheckFruitStockLevel( IN pFruitId SMALLINT(5), OUT pStockLevel VARCHAR(6)) BEGIN DECLARE stockNumber SMALLINT; SELECT Fruit.Inventory into stockNumber FROM Fruit INNER JOIN Units ON Fruit.UnitId = Units.UnitId WHERE Fruit.FruitId = pFruitId; IF stockNumber > 10 THEN SET pStockLevel = 'High'; ELSEIF (stockNumber <= 10 AND stockNumber >= 5) THEN SET pStockLevel = 'Medium'; ELSEIF (stockNumber < 5) THEN SET pStockLevel = 'Low - Please Replace Now!'; END IF; END // DELIMITER ;
El ejemplo anterior acepta dos modos diferentes de parámetros (IN
y OUT
). IN
es el predeterminado, por eso el ejemplo anterior no incluía el modo.
Aquí, también establecemos una variable. Usamos DECLARE stockNumber SMALLINT
para declarar una variable llamada stockNumber
con un tipo de SMALLINT
(entero pequeño).
Usamos un SELECT
declaración para buscar el inventario para la identificación de la fruta dada y asignarla a nuestro stockNumber
variables.
Finalmente, usamos un SQL IF
declaración para determinar el nivel de existencias, colocando este valor en el pStockLevel
parámetro (que por supuesto es el OUT
parámetro:este es el valor que veremos cuando llamemos al procedimiento almacenado).
Llamar a un procedimiento almacenado con OUT
o INOUT
Parámetro
En nuestro último ejemplo especificamos dos parámetros, un IN
parámetro y un OUT
parámetro.
Cuando llamamos a este procedimiento almacenado, aún necesitamos incluir el OUT
parámetro. Sin embargo, debido a que no sabremos su valor (después de todo, es por eso que lo llamamos, ¡para averiguar su valor!), necesitaremos usar una variable. Entonces podemos usar un SELECT
declaración para averiguar su valor.
Así:
CALL spCheckFruitStockLevel(1, @stockLevel); select @stockLevel;
Resultado:
Modos de parámetros
Solo usamos dos modos de parámetros (IN
y OUT
). En MySQL, hay tres modos de parámetros que se pueden usar con los procedimientos almacenados.
- EN
- Cuando usa este modo de parámetro, usted (o su aplicación) debe pasar el valor del parámetro cuando llama al procedimiento almacenado. Estos parámetros están protegidos. Por lo tanto, su valor original se conserva después de ejecutar el procedimiento almacenado. Si el procedimiento almacenado cambia el valor, solo lo hace en una copia del parámetro.
Este modo es el modo predeterminado. Si no proporciona el modo de parámetro, será
IN
. - FUERA
- El valor de un
OUT
El parámetro puede cambiar dentro del procedimiento almacenado y su valor se devuelve a la aplicación que llama. - ENTRADA
- Este modo es una combinación de
IN
yOUT
modos. Puede pasar el valor inicial, el procedimiento almacenado puede cambiarlo y devolverá el nuevo valor a la aplicación que llama.