Variables

Los procedimientos almacenados pueden usar variables locales declaradas con DECLARE y variables de sesión con el prefijo @. Las variables locales solo existen dentro del bloque BEGIN...END donde se declaran.

Variables locales con DECLARE

DELIMITER //
 
CREATE PROCEDURE ejemplo_variables()
BEGIN
    -- Declarar variables (siempre al inicio del bloque BEGIN)
    DECLARE nombre VARCHAR(100);
    DECLARE precio DECIMAL(10,2) DEFAULT 0.00;
    DECLARE cantidad INT DEFAULT 1;
    DECLARE activo BOOLEAN DEFAULT TRUE;
 
    -- Asignar valores con SET
    SET nombre = 'Producto de prueba';
    SET precio = 99.99;
 
    SELECT nombre, precio, cantidad, activo;
END //
 
DELIMITER ;
CALL ejemplo_variables();
nombrepreciocantidadactivo
Producto de prueba99.9911

Reglas de DECLARE

  1. DECLARE debe ir al inicio del bloque BEGIN...END, antes de cualquier otra sentencia
  2. Puedes declarar múltiples variables del mismo tipo en una línea
  3. El valor por defecto es NULL si no se especifica DEFAULT
DELIMITER //
 
CREATE PROCEDURE ejemplo_declare()
BEGIN
    -- Múltiples variables del mismo tipo
    DECLARE x, y, z INT DEFAULT 0;
 
    SET x = 10;
    SET y = 20;
    SET z = x + y;
 
    SELECT x, y, z;
END //
 
DELIMITER ;
CALL ejemplo_declare();
xyz
102030

Asignar valores con SELECT INTO

SELECT INTO permite asignar el resultado de una consulta a variables:

DELIMITER //
 
CREATE PROCEDURE info_producto(IN prod_id INT)
BEGIN
    DECLARE v_nombre VARCHAR(100);
    DECLARE v_precio DECIMAL(10,2);
    DECLARE v_stock INT;
 
    SELECT nombre, precio, stock
    INTO v_nombre, v_precio, v_stock
    FROM productos
    WHERE id = prod_id;
 
    SELECT v_nombre AS producto,
           v_precio AS precio,
           v_stock AS stock,
           v_precio * v_stock AS valor_inventario;
END //
 
DELIMITER ;
CALL info_producto(1);
productopreciostockvalor_inventario
iPhone 15 Pro1299.994558499.55

Variables de sesión

Las variables de sesión se crean con @ y persisten durante toda la sesión de conexión. No necesitan declaración:

-- Crear y asignar
SET @contador = 0;
SET @nombre = 'MySQL';
 
-- Usar en consultas
SELECT @contador, @nombre;
@contador@nombre
0MySQL
-- Asignar desde una consulta
SELECT @max_precio := MAX(precio) FROM productos;
SELECT @max_precio;
@max_precio
1899.99

Variables locales vs variables de sesión

CaracterísticaVariable localVariable de sesión
PrefijoSin prefijo@
DeclaraciónRequiere DECLARENo requiere
ÁmbitoBloque BEGIN...ENDToda la sesión
PersistenciaSolo durante la ejecuciónHasta cerrar conexión
Uso fuera del procedimientoNo

Ámbito de variables

DELIMITER //
 
CREATE PROCEDURE ejemplo_ambito()
BEGIN
    DECLARE x INT DEFAULT 10;
 
    BEGIN
        -- Este bloque interno puede acceder a x
        DECLARE y INT DEFAULT 20;
        SELECT x + y AS suma_interna;
    END;
 
    -- x sigue visible, pero y no existe aquí
    SELECT x AS valor_x;
    -- SELECT y; -- Error: Unknown column 'y'
END //
 
DELIMITER ;

Ejemplo práctico: calcular descuento

DELIMITER //
 
CREATE PROCEDURE calcular_descuento(IN prod_id INT)
BEGIN
    DECLARE v_nombre VARCHAR(100);
    DECLARE v_precio DECIMAL(10,2);
    DECLARE v_descuento DECIMAL(5,2) DEFAULT 0;
    DECLARE v_precio_final DECIMAL(10,2);
 
    SELECT nombre, precio INTO v_nombre, v_precio
    FROM productos WHERE id = prod_id;
 
    -- Calcular descuento según precio
    IF v_precio > 1000 THEN
        SET v_descuento = 15.00;
    ELSEIF v_precio > 500 THEN
        SET v_descuento = 10.00;
    ELSEIF v_precio > 100 THEN
        SET v_descuento = 5.00;
    END IF;
 
    SET v_precio_final = v_precio - (v_precio * v_descuento / 100);
 
    SELECT v_nombre AS producto,
           v_precio AS precio_original,
           v_descuento AS descuento_pct,
           v_precio_final AS precio_final;
END //
 
DELIMITER ;
CALL calcular_descuento(1);
productoprecio_originaldescuento_pctprecio_final
iPhone 15 Pro1299.9915.001104.99
CALL calcular_descuento(22);
productoprecio_originaldescuento_pctprecio_final
Camiseta algodón básica19.990.0019.99

Limpieza

DROP PROCEDURE IF EXISTS ejemplo_variables;
DROP PROCEDURE IF EXISTS ejemplo_declare;
DROP PROCEDURE IF EXISTS info_producto;
DROP PROCEDURE IF EXISTS ejemplo_ambito;
DROP PROCEDURE IF EXISTS calcular_descuento;

En el siguiente artículo veremos la sentencia IF para control de flujo dentro de procedimientos.

Escrito por Eduardo Lázaro