Tablas temporales y variables de tabla: conservar resultados durante un proceso
Algunas tareas necesitan separar una consulta compleja en etapas, reutilizar un conjunto o inspeccionarlo antes de modificar datos. SQL Server ofrece tablas temporales y variables de tabla para mantener resultados durante un alcance limitado. El alcance es la parte de la ejecución donde un nombre existe y puede utilizarse.
Ninguna es automáticamente mejor. La elección depende del volumen, las operaciones posteriores, los índices y el plan de ejecución. El optimizador es el componente de SQL Server que compara estrategias y el plan describe la estrategia elegida.
La idea
- Una tabla temporal local utiliza un nombre que comienza con
#y vive entempdb, la base de sistema que SQL Server utiliza para objetos y trabajo temporal, durante la sesión o el alcance correspondiente. - Una variable de tabla se declara con
@y respeta el alcance del lote, procedimiento o función donde fue creada.
Las dos almacenan datos en tempdb; la palabra variable no significa que todo permanezca únicamente en memoria.
Ejemplo: tabla temporal
Una tabla temporal local se crea con CREATE TABLE y un nombre que comienza con #. Su definición puede incluir tipos, nulabilidad, restricciones e índices.
CREATE TABLE #TablaTemporal
(
Columna TipoDeDato
);
CREATE TABLE #PedidosRecientes
(
IdPedido BIGINT NOT NULL PRIMARY KEY,
IdCliente INT NOT NULL,
FechaPedido DATETIME2(0) NOT NULL
);
INSERT INTO #PedidosRecientes
(IdPedido, IdCliente, FechaPedido)
SELECT
p.IdPedido,
p.IdCliente,
p.FechaPedido
FROM dbo.Pedido AS p
WHERE p.FechaPedido >= '2026-03-01';
SELECT
c.Nombre,
COUNT(*) AS CantidadPedidos
FROM #PedidosRecientes AS pr
INNER JOIN dbo.Cliente AS c
ON c.IdCliente = pr.IdCliente
GROUP BY c.Nombre;
DROP TABLE #PedidosRecientes;
La tabla puede consultarse varias veces dentro de su alcance. También podemos agregar índices cuando las operaciones posteriores lo justifican.
Ejemplo: variable de tabla
Una variable de tabla se declara con DECLARE, un nombre que comienza con @ y la palabra TABLE. Su estructura queda definida en la misma declaración.
DECLARE @VariableTabla TABLE
(
Columna TipoDeDato
);
DECLARE @ProductosSeleccionados TABLE
(
IdProducto INT NOT NULL PRIMARY KEY,
Precio DECIMAL(12, 2) NOT NULL
);
INSERT INTO @ProductosSeleccionados (IdProducto, Precio)
SELECT
p.IdProducto,
p.Precio
FROM dbo.Producto AS p
WHERE p.Activo = 1
AND p.Precio >= 500;
SELECT
ps.IdProducto,
ps.Precio
FROM @ProductosSeleccionados AS ps;
La variable resulta cómoda para conjuntos pequeños y de uso acotado. Su definición forma parte de la declaración y no necesita un DROP.
Comparación práctica
| Aspecto | Tabla temporal | Variable de tabla |
|---|---|---|
| Nombre | #Resultado |
@Resultado |
| Alcance típico | Sesión o procedimiento | Lote, procedimiento o función |
| Estadísticas | Sí, según el objeto y uso | Más limitadas |
| Índices posteriores | Permite crearlos | Principalmente mediante la definición |
| Reutilización en varias instrucciones | Sí | Sí, dentro de su alcance |
Versiones recientes de SQL Server pueden mejorar las estimaciones de variables de tabla mediante compilación diferida: aplazar la creación del plan hasta conocer las filas insertadas. Aun así, no debemos asumir que se comportarán igual que una tabla temporal para cualquier volumen.
También existe SELECT INTO, que crea y llena una tabla temporal con el resultado de una consulta. Es una forma breve, pero una definición explícita permite controlar tipos, nulabilidad —si una columna admite NULL— y restricciones antes de insertar.
Qué conviene comprobar
Observamos el número real de filas, la reutilización, las uniones posteriores y el plan de ejecución. Para conjuntos grandes o consultados varias veces, una tabla temporal con índices adecuados suele ofrecer más opciones al optimizador.
También debemos evitar crear etapas temporales por costumbre. Cada escritura y lectura añade trabajo en tempdb; una sola consulta clara puede ser suficiente.