Variables definidas por el usuario
Las variables definidas por el usuario en MySQL permiten almacenar valores temporales dentro de una sesión y reutilizarlos en consultas posteriores. Se identifican con el prefijo @ y persisten durante toda la conexión. Son una herramienta versátil para almacenar resultados intermedios, parametrizar consultas y simplificar operaciones complejas.
Sintaxis básica
Para asignar un valor a una variable usa SET o :=:
-- Con SET
SET @precio_limite = 500;
-- Con SELECT y :=
SELECT @total := COUNT(*) FROM productos;
-- Con SET y SELECT
SET @nombre_buscar = 'iPhone';Para leer el valor:
SELECT @precio_limite;| @precio_limite |
|---|
| 500 |
Usar variables en consultas
Las variables se pueden usar en cualquier lugar donde se acepte una expresión:
SET @categoria = 6;
SET @precio_min = 100;
SELECT nombre, precio
FROM productos
WHERE categoria_id = @categoria
AND precio >= @precio_min;| nombre | precio |
|---|---|
| iPhone 15 Pro | 1299.99 |
| Samsung Galaxy S24 | 899.99 |
| Google Pixel 8 | 699.00 |
Esto es particularmente útil para ejecutar la misma consulta con diferentes parámetros sin modificar el texto SQL:
SET @mes = 2;
SET @anio = 2026;
SELECT
DATE_FORMAT(fecha_pedido, '%Y-%m-%d') AS fecha,
COUNT(*) AS pedidos,
SUM(total) AS ingresos
FROM pedidos
WHERE MONTH(fecha_pedido) = @mes
AND YEAR(fecha_pedido) = @anio
GROUP BY DATE(fecha_pedido)
ORDER BY fecha;Almacenar resultados de consultas
Puedes capturar el resultado de una consulta en una variable:
SELECT @max_precio := MAX(precio),
@min_precio := MIN(precio),
@promedio := AVG(precio)
FROM productos;
SELECT
@max_precio AS precio_maximo,
@min_precio AS precio_minimo,
@promedio AS precio_promedio;| precio_maximo | precio_minimo | precio_promedio |
|---|---|---|
| 1899.99 | 9.99 | 356.78 |
Luego puedes usar estas variables en otras consultas:
-- Productos por encima del promedio
SELECT nombre, precio
FROM productos
WHERE precio > @promedio
ORDER BY precio DESC;Tipos de datos
Las variables de usuario pueden almacenar enteros, decimales, cadenas y NULL. El tipo se determina automáticamente por el valor asignado:
SET @entero = 42;
SET @decimal = 3.14;
SET @texto = 'Hola mundo';
SET @fecha = '2026-02-14';
SET @nulo = NULL;Si usas una variable no inicializada, su valor es NULL:
SELECT @variable_inexistente;| @variable_inexistente |
|---|
| NULL |
Variables como contadores
Las variables son útiles como contadores en consultas:
SET @fila = 0;
SELECT
@fila := @fila + 1 AS numero,
nombre,
precio
FROM productos
ORDER BY precio DESC
LIMIT 10;| numero | nombre | precio |
|---|---|---|
| 1 | ASUS ROG Zephyrus | 1899.99 |
| 2 | Lenovo ThinkPad X1 | 1549.00 |
| 3 | MacBook Air M3 | 1399.00 |
| 4 | iPhone 15 Pro | 1299.99 |
| 5 | Samsung Galaxy S24 | 899.99 |
Nota: desde MySQL 8.0, la función ROW_NUMBER() es la forma recomendada de numerar filas. Las variables de usuario como contadores pueden tener un comportamiento impredecible en consultas complejas con JOINs o subconsultas porque el orden de evaluación no está garantizado.
Acumular valores
Puedes usar variables para calcular totales acumulados:
SET @acumulado = 0;
SELECT
nombre,
precio,
@acumulado := @acumulado + precio AS precio_acumulado
FROM productos
WHERE categoria_id = 6
ORDER BY precio;| nombre | precio | precio_acumulado |
|---|---|---|
| Xiaomi 14 | 599.99 | 599.99 |
| Google Pixel 8 | 699.00 | 1298.99 |
| Samsung Galaxy S24 | 899.99 | 2198.98 |
| iPhone 15 Pro | 1299.99 | 3498.97 |
En MySQL 8.0+, la función de ventana SUM() OVER() es más fiable para acumulados:
SELECT
nombre,
precio,
SUM(precio) OVER (ORDER BY precio) AS precio_acumulado
FROM productos
WHERE categoria_id = 6;Variables en procedimientos almacenados
Dentro de procedimientos almacenados, las variables locales (declaradas con DECLARE) son preferibles a las variables de usuario. Sin embargo, las variables de usuario son útiles cuando necesitas pasar datos entre consultas en una sesión sin usar procedimientos:
-- Guardar el ID del último pedido insertado
INSERT INTO pedidos (cliente_id, total) VALUES (1, 499.99);
SET @ultimo_pedido = LAST_INSERT_ID();
-- Usar ese ID en la siguiente operación
INSERT INTO detalle_pedidos (pedido_id, producto_id, cantidad, precio_unitario)
VALUES
(@ultimo_pedido, 1, 1, 299.99),
(@ultimo_pedido, 9, 1, 199.99);Alcance de las variables
Las variables de usuario son locales a la sesión (conexión). Cada conexión tiene su propio conjunto de variables. Cuando la conexión se cierra, todas las variables se pierden. Dos sesiones pueden tener variables con el mismo nombre sin interferir entre sí.
-- Sesión 1
SET @usuario = 'admin';
-- Sesión 2 (independiente)
SET @usuario = 'operador';
-- Cada sesión ve solo su propio valorPrecauciones
No confíes en el orden de evaluación de las variables dentro de una misma sentencia SELECT. MySQL no garantiza que las asignaciones se evalúen en un orden específico cuando hay múltiples asignaciones en la misma consulta. Para resultados predecibles, usa consultas separadas o funciones de ventana.
Las variables de usuario no deben usarse para controlar la seguridad o el acceso, ya que cualquier usuario puede cambiar sus propias variables. Tampoco deben usarse en aplicaciones multi-hilo que comparten conexiones de pool sin reiniciar las variables.
Las variables definidas por el usuario son una herramienta conveniente para trabajo interactivo y scripting en MySQL. Para aplicaciones de producción, los prepared statements y los procedimientos almacenados con variables locales son generalmente más apropiados.
Escrito por Eduardo Lázaro
