DECLARE, SET y asignación con SELECT: trabajar con variables

Una consulta reutilizable no debería obligarnos a modificar valores dispersos dentro del código. Las variables permiten nombrar una fecha, un identificador, un límite o un resultado intermedio y utilizarlo durante el lote o procedimiento.

DECLARE crea la variable. SET y SELECT pueden asignarle valores, pero no se comportan igual en todos los casos.

Declarar y asignar

DECLARE @IdCategoria SMALLINT;
DECLARE @PrecioMaximo DECIMAL(12, 2);

SET @IdCategoria = 1;
SET @PrecioMaximo = 500.00;

El nombre comienza con @ y el tipo define qué valores puede recibir. También podemos declarar e inicializar en una sola línea:

DECLARE @FechaDesde DATE = '2026-03-01';

Ejemplo: utilizar variables en una consulta

DECLARE @IdCategoria SMALLINT = 1;
DECLARE @PrecioMaximo DECIMAL(12, 2) = 500.00;

SELECT
    p.IdProducto,
    p.Nombre,
    p.Precio
FROM dbo.Producto AS p
WHERE p.IdCategoria = @IdCategoria
  AND p.Precio <= @PrecioMaximo
ORDER BY p.Precio;

Las variables viven únicamente dentro de su alcance. No son parámetros recibidos automáticamente desde una aplicación; un procedimiento debe declararlos como parte de su firma.

Asignar el resultado de una consulta

SET puede recibir una subconsulta que devuelve un solo valor:

DECLARE @PrecioPromedio DECIMAL(12, 2);

SET @PrecioPromedio =
(
    SELECT AVG(p.Precio)
    FROM dbo.Producto AS p
    WHERE p.Activo = 1
);

SELECT @PrecioPromedio AS PrecioPromedio;

SELECT permite asignar varias variables en la misma consulta:

DECLARE @CantidadProductos INT;
DECLARE @PrecioMayor DECIMAL(12, 2);

SELECT
    @CantidadProductos = COUNT(*),
    @PrecioMayor = MAX(p.Precio)
FROM dbo.Producto AS p
WHERE p.Activo = 1;

Diferencias importantes

Si una subconsulta escalar utilizada por SET devuelve varias filas, SQL Server genera un error. Una asignación mediante SELECT @Variable = Columna FROM ... puede asignar repetidamente y terminar con uno de los valores procesados; sin un diseño que garantice una sola fila, el resultado no representa una elección confiable.

Cuando una asignación con SELECT no encuentra filas, la variable puede conservar su valor anterior. Por eso no debemos utilizarla como si siempre asignara NULL automáticamente.

Qué conviene comprobar

El tipo de la variable debe coincidir con el dato que representa. Una longitud insuficiente puede truncar texto y una escala inadecuada puede redondear números.

También distinguimos una variable local de un parámetro y de una columna. Utilizar prefijos descriptivos como @FechaDesde o @IdCliente facilita reconocer la intención sin agregar comentarios innecesarios.

Relacionado con

  • Procedimientos almacenados: reciben parámetros con una sintaxis parecida.
  • IF y WHILE: utilizan variables para decidir y controlar ejecución.
  • Conversiones: permiten alinear explícitamente el tipo asignado.
  • SELECT: puede calcular uno o varios valores para las variables.