CREATE PROCEDURE

CREATE PROCEDURE define un nuevo procedimiento almacenado en la base de datos. El procedimiento puede contener cualquier sentencia SQL, variables, condicionales y bucles.

Sintaxis

DELIMITER //
 
CREATE PROCEDURE nombre_procedimiento(lista_parametros)
[características]
BEGIN
    -- Cuerpo del procedimiento
    sentencias_sql;
END //
 
DELIMITER ;

Características opcionales

CREATE PROCEDURE nombre()
COMMENT 'Descripción del procedimiento'
DETERMINISTIC           -- Siempre devuelve el mismo resultado para los mismos parámetros
-- o NOT DETERMINISTIC   -- Por defecto
SQL SECURITY DEFINER     -- Se ejecuta con permisos del creador (por defecto)
-- o SQL SECURITY INVOKER -- Se ejecuta con permisos del que lo llama
BEGIN
    -- ...
END
CaracterísticaOpcionesPor defecto
DETERMINISTICDETERMINISTIC, NOT DETERMINISTICNOT DETERMINISTIC
SQL SECURITYDEFINER, INVOKERDEFINER
COMMENTCualquier textoVacío

Ejemplo básico

DELIMITER //
 
CREATE PROCEDURE obtener_productos_activos()
BEGIN
    SELECT id, nombre, precio, stock
    FROM productos
    WHERE activo = TRUE
    ORDER BY nombre;
END //
 
DELIMITER ;
CALL obtener_productos_activos();
idnombrepreciostock
18ASUS ROG Zephyrus1899.9912
25Auriculares Bluetooth49.99150
22Camiseta algodón básica19.99200
............

Procedimiento con lógica

DELIMITER //
 
CREATE PROCEDURE resumen_tienda()
BEGIN
    SELECT COUNT(*) AS total_productos FROM productos WHERE activo = TRUE;
    SELECT COUNT(*) AS total_clientes FROM clientes;
    SELECT COUNT(*) AS total_pedidos FROM pedidos;
    SELECT SUM(total) AS ingresos_totales FROM pedidos;
END //
 
DELIMITER ;
CALL resumen_tienda();

Este procedimiento devuelve cuatro conjuntos de resultados, uno por cada SELECT.

Procedimiento con variables

DELIMITER //
 
CREATE PROCEDURE estadisticas_producto(IN prod_id INT)
BEGIN
    DECLARE nombre_prod VARCHAR(100);
    DECLARE precio_prod DECIMAL(10,2);
    DECLARE total_ventas INT;
 
    SELECT nombre, precio INTO nombre_prod, precio_prod
    FROM productos WHERE id = prod_id;
 
    SELECT COALESCE(SUM(cantidad), 0) INTO total_ventas
    FROM detalle_pedidos WHERE producto_id = prod_id;
 
    SELECT nombre_prod AS producto,
           precio_prod AS precio,
           total_ventas AS unidades_vendidas,
           precio_prod * total_ventas AS ingreso_total;
END //
 
DELIMITER ;
CALL estadisticas_producto(1);
productopreciounidades_vendidasingreso_total
iPhone 15 Pro1299.9945199.96

BEGIN...END anidados

DELIMITER //
 
CREATE PROCEDURE ejemplo_bloques()
BEGIN
    -- Bloque exterior
    DECLARE x INT DEFAULT 10;
 
    BEGIN
        -- Bloque interior
        DECLARE y INT DEFAULT 20;
        SELECT x + y AS suma;
    END;
 
    -- y no es visible aquí
    SELECT x AS valor_x;
END //
 
DELIMITER ;

Verificar que existe

-- Listar procedimientos
SHOW PROCEDURE STATUS WHERE Db = 'tienda_mysql'\G
-- Ver la definición
SHOW CREATE PROCEDURE estadisticas_producto\G
-- Desde information_schema
SELECT ROUTINE_NAME, ROUTINE_TYPE, CREATED
FROM information_schema.ROUTINES
WHERE ROUTINE_SCHEMA = 'tienda_mysql'
AND ROUTINE_TYPE = 'PROCEDURE';

Limpieza

DROP PROCEDURE IF EXISTS obtener_productos_activos;
DROP PROCEDURE IF EXISTS resumen_tienda;
DROP PROCEDURE IF EXISTS estadisticas_producto;
DROP PROCEDURE IF EXISTS ejemplo_bloques;

En el siguiente artículo veremos los parámetros IN, OUT e INOUT que permiten pasar y recibir datos de los procedimientos.

Escrito por Eduardo Lázaro