En el vasto universo de la gestión de bases de datos, MySQL se destaca por su flexibilidad y potencia. Una de las características que a menudo resulta extremadamente útil para los desarrolladores y administradores son las variables de usuario, fácilmente identificables por el prefijo '@'. Estas variables ofrecen una forma sencilla y eficaz de almacenar información temporalmente dentro de una sesión de base de datos, permitiendo pasar valores entre diferentes sentencias SQL.

A diferencia de las variables del sistema (que controlan la configuración del servidor) o las variables locales dentro de procedimientos almacenados, las variables de usuario son efímeras y específicas de la conexión actual. Son una herramienta valiosa para simplificar lógica compleja, almacenar resultados intermedios o construir consultas dinámicamente.

- ¿Qué son las Variables de Usuario (@variable)?
- Cómo Establecer Valores en Variables de Usuario
- Alcance y Ciclo de Vida de las Variables de Usuario
- Tipos de Datos y Conversiones
- Variables No Inicializadas y Determinación de Tipo
- Dónde Usar (y Dónde No Usar) Variables de Usuario
- Consideraciones Importantes y Posibles Problemas
- Tabla Comparativa Simple (Variable de Usuario vs. Literal)
- Preguntas Frecuentes (FAQ)
- ¿Son las variables de usuario sensibles a mayúsculas y minúsculas?
- ¿Cuánto duran las variables de usuario?
- ¿Puedo usar una variable de usuario en la cláusula LIMIT?
- ¿Por qué mi variable de usuario da NULL si creo que la asigné?
- ¿Es seguro usar variables de usuario para construir consultas dinámicas?
- Conclusión
¿Qué son las Variables de Usuario (@variable)?
Las variables de usuario en MySQL son contenedores temporales donde puedes guardar un valor en una sentencia SQL y referenciarlo más adelante en otra. Imagina que necesitas calcular algo en un paso y usar ese resultado en el siguiente sin tener que recalcularlo o almacenar temporalmente en una tabla. Ahí es donde entran en juego las variables de usuario.
Se distinguen por comenzar con el símbolo '@', seguido del nombre que elijas para la variable. Por ejemplo, @mi_variable, @total_registros, @suma_temporal. El nombre de la variable puede consistir en caracteres alfanuméricos (letras y números), el punto (.), el guion bajo (_) y el signo de dólar ($). Si necesitas usar otros caracteres en el nombre (como espacios o guiones), deberás citarlo como una cadena o un identificador, por ejemplo: @'mi-variable con espacios', @"otra-variable", o @`variable.con.puntos`.
Un aspecto importante es que los nombres de las variables de usuario no son sensibles a mayúsculas y minúsculas. Así, @mi_variable, @Mi_Variable y @MI_VARIABLE se refieren a la misma variable. La longitud máxima permitida para un nombre de variable de usuario es de 64 caracteres.
Cómo Establecer Valores en Variables de Usuario
La forma más común y recomendada para asignar un valor a una variable de usuario es utilizando la sentencia SET. La sintaxis es bastante directa:
SET @nombre_variable = expresion;
O puedes asignar múltiples variables en una sola sentencia:
SET @var1 = valor1, @var2 = valor2;
Dentro de una sentencia SET, puedes usar tanto el operador de asignación = como :=. Ambos funcionan de la misma manera en este contexto.
Ejemplos:
SET @mi_numero = 100; SET @mi_texto = 'Hola Mundo'; SET @fecha_actual = CURDATE(); SET @total = (SELECT COUNT(*) FROM mi_tabla);Históricamente, MySQL permitía asignar valores a variables de usuario directamente en otras sentencias (como SELECT o UPDATE) utilizando exclusivamente el operador := (ya que = se interpreta como un operador de comparación en esos contextos). Aunque esta funcionalidad aún se soporta en versiones recientes (como MySQL 8.4) por compatibilidad hacia atrás, está sujeta a ser eliminada en futuras versiones. Por lo tanto, la práctica recomendada es utilizar siempre la sentencia SET para asignar valores a variables de usuario.
Alcance y Ciclo de Vida de las Variables de Usuario
Las variables de usuario son específicas de la sesión del cliente. Esto significa que una variable definida por un cliente (por ejemplo, una conexión a la base de datos desde una aplicación o la línea de comandos) no puede ser vista ni utilizada por otros clientes conectados al mismo servidor MySQL. Son completamente aisladas.
El ciclo de vida de estas variables está ligado a la sesión. Todas las variables definidas por un cliente se liberan automáticamente de la memoria cuando esa conexión de cliente finaliza (por ejemplo, cuando cierras el programa cliente o la conexión se interrumpe). No persisten entre sesiones ni después de que el servidor MySQL se reinicia.
Existe una excepción para usuarios con permisos especiales: aquellos con acceso a la tabla user_variables_by_thread dentro del Performance Schema pueden ver todas las variables de usuario para todas las sesiones activas. Sin embargo, esta es una capacidad de monitoreo y no de uso cruzado de variables.
Tipos de Datos y Conversiones
Las variables de usuario pueden almacenar valores de un conjunto limitado de tipos de datos:
- Enteros (INTEGER)
- Decimales (DECIMAL)
- Punto flotante (FLOAT, DOUBLE)
- Cadenas binarias o no binarias (STRING BINARY/NONBINARY)
- Valor NULL
Cuando asignas un valor de un tipo de dato diferente, MySQL intentará convertirlo a uno de los tipos permitidos. Por ejemplo:
- Valores de tipos temporales (DATE, TIME, DATETIME) o espaciales se convierten a cadenas binarias.
- Valores de tipo JSON se convierten a una cadena con el juego de caracteres
utf8mb4y la intercalaciónutf8mb4_bin.
Es importante notar que la asignación de valores decimales o de punto flotante (reales) a una variable de usuario no garantiza que se preserve la precisión o escala exactas del valor original. Pueden ocurrir aproximaciones.
Si asignas una cadena no binaria (de caracteres), la variable heredará el mismo juego de caracteres y la misma intercalación que la cadena original. La "coercibilidad" de las variables de usuario (cómo se manejan en comparaciones y operaciones) es implícita, similar a la de los valores de las columnas de tabla.
Manejo de Valores Hexadecimales y Bits
Los valores hexadecimales (X'...') o de bits (b'...') asignados directamente a variables de usuario se tratan por defecto como cadenas binarias. Si deseas que se traten como números, debes usarlos en un contexto numérico. Esto se logra sumando 0 o utilizando CAST(... AS UNSIGNED):
-- X'41' es el código ASCII para 'A' SET @v1 = X'41'; -- @v1 contendrá la cadena binaria 'A' SET @v2 = X'41' + 0; -- @v2 contendrá el número 65 (valor decimal de 65) SET @v3 = CAST(X'41' AS UNSIGNED); -- @v3 contendrá el número 65 SELECT @v1, @v2, @v3; -- Resultado: 'A', 65, 65 -- b'1000001' es la representación binaria del número 65 SET @v4 = b'1000001'; -- @v4 contendrá la cadena binaria 'A' SET @v5 = b'1000001' + 0; -- @v5 contendrá el número 65 SET @v6 = CAST(b'1000001' AS UNSIGNED); -- @v6 contendrá el número 65 SELECT @v4, @v5, @v6; -- Resultado: 'A', 65, 65Cuando seleccionas el valor de una variable de usuario en el conjunto de resultados de una consulta SELECT, este valor se devuelve al cliente como una cadena, independientemente de su tipo interno.
Variables No Inicializadas y Determinación de Tipo
Si intentas referenciar una variable de usuario que no ha sido inicializada previamente con un valor, MySQL le asignará automáticamente un valor NULL y un tipo de dato 'cadena'.
Un comportamiento particular ocurre en sentencias preparadas (PREPARE/EXECUTE) y dentro de procedimientos almacenados. El tipo de dato de una variable de usuario utilizada en estos contextos se determina la primera vez que la sentencia preparada se ejecuta o el procedimiento almacenado se invoca. Una vez determinado, este tipo se mantiene fijo para esa variable en ejecuciones posteriores de la misma sentencia preparada o invocaciones del mismo procedimiento, incluso si intentas asignarle un valor de un tipo diferente más adelante dentro del mismo contexto.
Dónde Usar (y Dónde No Usar) Variables de Usuario
Las variables de usuario pueden ser utilizadas en la mayoría de los contextos donde se permiten expresiones. Esto incluye:
- En la lista de selección de un
SELECT. - En la cláusula
WHEREpara filtrar resultados. - En cálculos dentro de cualquier parte de la consulta.
- En sentencias
INSERT,UPDATE,DELETE.
Sin embargo, hay contextos específicos que requieren un valor literal y donde las variables de usuario *no* pueden ser utilizadas directamente. Los ejemplos más comunes son:
- En la cláusula
LIMITde una sentenciaSELECT(para especificar el desplazamiento o el número de filas). - En la cláusula
IGNORE N LINESde una sentenciaLOAD DATA.
Además, y esto es fundamental, las variables de usuario están diseñadas para almacenar *valores de datos*. No pueden ser utilizadas directamente en una sentencia SQL como un identificador o parte de un identificador. Esto significa que no puedes usar una variable de usuario donde se espera un nombre de tabla, un nombre de columna, un nombre de base de datos, o una palabra reservada de SQL (como SELECT, FROM, etc.). Esto es cierto incluso si intentas citar la variable.
-- Ejemplo de lo que NO se puede hacer: SET @nombre_columna = 'nombre'; SELECT @nombre_columna FROM mi_tabla; -- Esto selecciona el VALOR '@nombre_columna', no el contenido de la columna 'nombre' SET @nombre_columna_citada = '`nombre`'; SELECT @nombre_columna_citada FROM mi_tabla; -- Esto también selecciona el VALOR '`nombre`' -- Intentar usarlo como identificador real falla: SELECT `@nombre_columna_citada` FROM mi_tabla; -- ERROR! MySQL busca una columna LITERAL llamada '@nombre_columna_citada'Construyendo SQL Dinámico con Variables de Usuario
A pesar de la limitación anterior, las variables de usuario son extremadamente útiles para construir *cadenas* que luego se ejecutarán como sentencias SQL. Esta técnica se conoce como SQL Dinámico.
La forma principal de lograr esto en MySQL es utilizando sentencias preparadas:
-- Supongamos que tenemos una tabla 'usuarios' con columnas 'id' y 'nombre' SET @columna_a_seleccionar = 'nombre'; SET @sentencia_sql = CONCAT('SELECT ', @columna_a_a_seleccionar, ' FROM usuarios WHERE id = 1'); -- @sentencia_sql ahora contiene la cadena 'SELECT nombre FROM usuarios WHERE id = 1' -- Preparamos la sentencia usando la cadena construida PREPARE stmt FROM @sentencia_sql; -- Ejecutamos la sentencia preparada EXECUTE stmt; -- Liberamos la sentencia preparada DEALLOCATE PREPARE stmt;Este patrón permite que partes de tu consulta, como nombres de columnas o tablas (si se manejan con precaución para evitar inyección SQL), se determinen dinámicamente en tiempo de ejecución.
Consideraciones Importantes y Posibles Problemas
Si bien las variables de usuario son poderosas, es crucial ser consciente de ciertas peculiaridades para evitar resultados inesperados:
- Orden de Evaluación Indefinido: El orden en que MySQL evalúa las expresiones que involucran variables de usuario es generalmente indefinido. Esto es particularmente problemático si intentas leer y asignar un nuevo valor a la *misma* variable dentro de la *misma* sentencia. Por ejemplo, en
SELECT @a, @a := @a + 1;, no hay garantía de que@ase lea antes de que se le asigne el nuevo valor incrementado. Para evitar este comportamiento impredecible, la regla general es: no asignes y leas el valor de la misma variable dentro de una única sentencia SQL. Si necesitas hacerlo, divídelo en múltiples sentenciasSEToSELECTseparadas. - Tipo de Resultado por Defecto: El tipo de dato que MySQL espera de una variable en una expresión se basa en el tipo que tenía la variable al *comienzo* de la sentencia. Esto puede tener efectos no deseados si, dentro de la misma sentencia, asignas un nuevo valor a la variable que tiene un tipo diferente. Para mitigar esto, es una buena práctica inicializar tus variables con un valor del tipo de dato esperado (por ejemplo,
SET @mi_var = 0;para un número entero,SET @mi_var = 0.0;para un número decimal, oSET @mi_var = '';para una cadena) antes de usarlas en sentencias complejas. - Uso con HAVING, GROUP BY, ORDER BY: Si asignas un valor a una variable de usuario en la lista de selección (
SELECT @var := expresion, ...) y luego intentas usar esa variable en las cláusulasHAVING,GROUP BYuORDER BYde la misma consulta, los resultados pueden no ser los esperados. Esto se debe a que estas cláusulas a menudo procesan los datos antes de que se evalúe completamente la lista de selección o pueden usar valores "antiguos" de la variable de filas procesadas previamente. De nuevo, es mejor asignar la variable en una sentencia separada (usandoSET) o, si la lógica lo permite, usar subconsultas o Common Table Expressions (CTEs) para garantizar el orden de evaluación.
Tabla Comparativa Simple (Variable de Usuario vs. Literal)
Aunque no es una comparación de tipos de variables, ayuda a entender la diferencia de uso:
| Característica | Variable de Usuario (@variable) | Valor Literal |
|---|---|---|
| Representa | Un valor almacenado temporalmente | El valor en sí mismo, fijo en la sentencia |
| Flexibilidad | Puede cambiar de valor, pasar entre sentencias | Fijo para esa sentencia |
| Uso como Identificador | No directamente (solo vía SQL Dinámico) | Puede ser parte de identificadores (si se cita) o valores |
| Ámbito | Sesión del cliente | La sentencia actual |
| Ejemplo (Valor) | SET @num = 10; SELECT @num; | SELECT 10; |
| Ejemplo (Identificador) | SET @col = 'nombre'; PREPARE stmt FROM CONCAT('SELECT ',@col,' FROM tabla'); EXECUTE stmt; | SELECT nombre FROM tabla; o SELECT `mi columna con espacios` FROM tabla; |
Preguntas Frecuentes (FAQ)
¿Son las variables de usuario sensibles a mayúsculas y minúsculas?
No, los nombres de las variables de usuario en MySQL no distinguen entre mayúsculas y minúsculas. @MiVar es lo mismo que @mivar.
¿Cuánto duran las variables de usuario?
Duran mientras dure la sesión del cliente que las definió. Se liberan automáticamente cuando la conexión se cierra.
¿Puedo usar una variable de usuario en la cláusula LIMIT?
No, LIMIT requiere valores literales (constantes). No puedes usar una variable de usuario directamente en LIMIT.
¿Por qué mi variable de usuario da NULL si creo que la asigné?
Puede haber varias razones: 1) La sentencia de asignación falló o no se ejecutó. 2) Estás intentando acceder a ella desde una sesión de cliente diferente. 3) Estás utilizando la variable en un contexto donde el orden de evaluación es incierto (ver consideraciones importantes).
¿Es seguro usar variables de usuario para construir consultas dinámicas?
Construir consultas dinámicas (SQL Dinámico) siempre conlleva riesgos de seguridad, principalmente la inyección SQL, si los valores que se concatenan provienen de entradas de usuario no validadas o escapadas correctamente. Si construyes partes de la consulta (como nombres de tabla o columna) basándote en datos externos, debes implementar validaciones estrictas y/o mecanismos de escapado para asegurar que no se pueda inyectar código malicioso.
Conclusión
Las variables de usuario con el prefijo @ son una característica poderosa y flexible de MySQL que permite a los usuarios almacenar y manipular valores temporales dentro de una sesión. Son ideales para optimizar consultas complejas, almacenar resultados intermedios o facilitar la construcción de sentencias SQL dinámicas (con las debidas precauciones de seguridad). Comprender su alcance (sesión específica), sus tipos de datos, cómo asignarlas correctamente (preferiblemente con SET y :=) y sus limitaciones es fundamental para utilizarlas de manera efectiva y evitar sorpresas. Al dominar esta herramienta, puedes escribir scripts y procedimientos MySQL más eficientes y legibles.
Si quieres conocer otros artículos parecidos a Variables de Usuario MySQL: El Poder de @variable puedes visitar la categoría MySQL.

Aprende mas sobre MySQL