Como crear un procedimiento almacenado con parametros en SQL Server
Un procedimiento almacenado (stored procedure) es un bloque de T-SQL guardado en la base de datos que puedes ejecutar siempre que lo necesites, y los parametros lo hacen flexible: pasas valores distintos y obtienes resultados distintos sin reescribir la consulta. Saber como crear un procedimiento almacenado con parametros en SQL Server te ayuda a centralizar la logica, reducir la repeticion y proteger tus consultas frente a la SQL injection. Ademas, SQL Server guarda el plan de ejecucion del procedimiento, lo que puede mejorar el rendimiento cuando lo ejecutas muchas veces.
Requisitos previos
- Una instancia de SQL Server (sirve el gratuito SQL Server Express).
- SQL Server Management Studio (SSMS) o Azure Data Studio para ejecutar las consultas.
- Una base de datos donde puedas crear objetos y el permiso
CREATE PROCEDURE. - Conocer lo basico de
SELECTyWHERE.
Paso 1: Crear una tabla de ejemplo
Para probar, necesitamos datos. Crea una tabla sencilla de ventas e inserta algunas filas. Los valores son ficticios y estan solo para que veas el procedimiento devolviendo resultados. Ejecuta este codigo en tu base de datos de prueba:
CREATE TABLE dbo.Vendas (
VendaID INT IDENTITY(1,1) PRIMARY KEY,
Cliente NVARCHAR(100),
Pais NVARCHAR(50),
Valor DECIMAL(10,2),
DataVenda DATE
);
INSERT INTO dbo.Vendas (Cliente, Pais, Valor, DataVenda) VALUES
('Ana Silva', 'Portugal', 120.50, '2026-01-15'),
('Joao Costa', 'Portugal', 340.00, '2026-02-03'),
('Marta Ruiz', 'Espanha', 85.90, '2026-02-20'),
('Pedro Alves', 'Portugal', 210.00, '2026-03-11');
Paso 2: Crear el procedimiento almacenado con un parametro
Ahora crea el procedimiento. El parametro de entrada empieza con @ y tiene un tipo de datos, igual que una columna. Este procedimiento devuelve las ventas de un pais que tu elijas:
CREATE PROCEDURE dbo.ObterVendasPorPais
@Pais NVARCHAR(50)
AS
BEGIN
SET NOCOUNT ON;
SELECT Cliente, Valor, DataVenda
FROM dbo.Vendas
WHERE Pais = @Pais
ORDER BY DataVenda;
END;
SET NOCOUNT ON evita mensajes innecesarios de "filas afectadas" y hace el procedimiento algo mas rapido. @Pais se comporta como una variable dentro del procedimiento. Da al parametro el mismo tipo de datos que la columna que vas a comparar (aqui, NVARCHAR(50)); los tipos incompatibles obligan a SQL Server a hacer conversiones que pueden ralentizar la consulta.
Paso 3: Ejecutar el procedimiento almacenado
Para ejecutar el procedimiento usas EXEC seguido del valor del parametro. Puedes pasar el valor de forma posicional o, mejor todavia, con el nombre del parametro (mas legible):
-- Forma posicional
EXEC dbo.ObterVendasPorPais 'Portugal';
-- Forma nomeada (recomendada)
EXEC dbo.ObterVendasPorPais @Pais = 'Espanha';
Cada llamada devuelve solo las filas del pais indicado. Cambiaste el resultado sin tocar la consulta: ese es el poder de los parametros.
Consejo de seguridad: pasar los valores como parametros, en lugar de concatenarlos directamente en el texto de la consulta, es la forma correcta de evitar la SQL injection. El procedimiento trata el valor siempre como dato, nunca como codigo.
Paso 4: Varios parametros y un valor por defecto
Puedes tener tantos parametros como quieras. Un parametro con valor por defecto se vuelve opcional: si no lo pasas, usa el valor definido. Aqui anadimos un importe minimo que por defecto es 0. Usa CREATE OR ALTER para actualizar el procedimiento sin borrarlo primero:
CREATE OR ALTER PROCEDURE dbo.ObterVendasPorPais
@Pais NVARCHAR(50),
@ValorMinimo DECIMAL(10,2) = 0
AS
BEGIN
SET NOCOUNT ON;
SELECT Cliente, Valor, DataVenda
FROM dbo.Vendas
WHERE Pais = @Pais
AND Valor >= @ValorMinimo
ORDER BY Valor DESC;
END;
Ahora tienes dos formas de llamar al procedimiento:
-- Usa o valor por omissao (@ValorMinimo = 0)
EXEC dbo.ObterVendasPorPais @Pais = 'Portugal';
-- Passa os dois parametros
EXEC dbo.ObterVendasPorPais @Pais = 'Portugal', @ValorMinimo = 200;
Paso 5: Devolver un valor con un parametro OUTPUT
A veces quieres devolver un unico valor, como un total o un recuento, en lugar de una tabla. Para eso usa un parametro OUTPUT: el valor que le asignas dentro del procedimiento queda disponible para quien lo llamo.
CREATE OR ALTER PROCEDURE dbo.ContarVendasPorPais
@Pais NVARCHAR(50),
@Total INT OUTPUT
AS
BEGIN
SET NOCOUNT ON;
SELECT @Total = COUNT(*)
FROM dbo.Vendas
WHERE Pais = @Pais;
END;
Para ejecutarlo, declara una variable que recibira el resultado y marcala tambien con OUTPUT en la llamada:
DECLARE @n INT;
EXEC dbo.ContarVendasPorPais @Pais = 'Portugal', @Total = @n OUTPUT;
PRINT 'Vendas em Portugal: ' + CAST(@n AS NVARCHAR(10));
Verificar el resultado
Confirma que el procedimiento existe consultando la vista de sistema sys.procedures:
SELECT name, create_date, modify_date
FROM sys.procedures
WHERE name IN ('ObterVendasPorPais', 'ContarVendasPorPais');
En SSMS tambien lo ves en Object Explorer, dentro de la base de datos, en Programmability > Stored Procedures. Si al ejecutar EXEC dbo.ObterVendasPorPais @Pais = 'Portugal' obtienes las filas esperadas, todo funciona.
Conclusion
Ya sabes como crear un procedimiento almacenado con uno o varios parametros, definir valores por defecto y devolver resultados con un parametro OUTPUT. Como la logica queda guardada en un solo sitio, puedes reutilizarla desde aplicaciones, informes u otros procedimientos sin copiar codigo. El siguiente paso natural es hacer el procedimiento mas robusto con manejo de errores usando TRY...CATCH y transacciones, para que las operaciones de escritura queden consistentes. Que parametro anadiras primero a tu proximo procedimiento: una fecha de inicio o un limite de importe?