funciones-definidas-usuario-udf-en-sql

Funciones Definidas por el Usuario (UDF) en SQL

  • 4 min

Una Función Definida por el Usuario (User Defined Function o UDF) es una rutina que acepta parámetros, realiza una acción y devuelve el resultado de esa acción como un valor.

Nos permiten realizar cálculos, transformaciones y operaciones complejas de manera modular, lo que mejora la legibilidad y mantenibilidad nuestro código T-SQL.

Las funciones están diseñadas para ser integradas directamente dentro de otras consultas. La filosofía es “Escríbelo una vez, úsalo muchas”.

Existen principalmente dos tipos que debes dominar: las Escalares y las de Tabla.

Funciones escalares

Son idénticas en concepto a UPPER() o ABS(). Reciben uno o varios parámetros y devuelven un único valor (un número, una fecha, un texto…).

La sintaxis es la siguiente,

CREATE FUNCTION dbo.NombreFuncion
(
    @Parametro TipoDato
)
RETURNS TipoDatoRetorno
AS
BEGIN
    DECLARE @Resultado TipoDatoRetorno;
    
    -- Lógica del cálculo
    SET @Resultado = ...;
    
    RETURN @Resultado;
END
Copied!

Las funciones escalares en versiones antiguas de SQL Server (y aún hoy si se abusa) pueden ser lentas porque se ejecutan fila a fila y evitan el paralelismo.

Úsalas para cálculos simples, pero tampoco abuses. Evita acceder a tablas (hacer SELECT) dentro de una función escalar si procesas millones de filas y puedes resolverlo de otra forma.

Funciones de tabla

Estas funciones no devuelven un dato suelto, sino una tabla completa. Son como una “Vista con Parámetros”.

Nos enfocaremos en las Inline TVF (Funciones de tabla en línea), que son las más rápidas.

La sintaxis es la siguiente,

CREATE FUNCTION dbo.ufn_ObtenerPedidosPorCliente
(
    @ClienteID INT
)
RETURNS TABLE
AS
RETURN
(
    SELECT PedidoID, Fecha, Total
    FROM Pedidos
    WHERE ClienteID = @ClienteID
);
Copied!

No tienen BEGIN...END. Simplemente retornan el resultado de una consulta.

Para usarlas, como devuelven una tabla, las usamos en la cláusula FROM o JOIN, (no en el SELECT).

SELECT Pedidos.PedidoID, Pedidos.Total
FROM dbo.ufn_ObtenerPedidosPorCliente(5) AS Pedidos -- ¡Actúa como una tabla!
WHERE Pedidos.Total > 100;
Copied!

Esto es mucho más limpio y modular que escribir el WHERE repetidamente en cada consulta.

Limitaciones de las UDF

Para mantener la integridad y el determinismo, SQL Server impone reglas estrictas a las funciones:

  1. Sin efectos secundarios: Una función no puede cambiar el estado de la base de datos. Nada de INSERT, UPDATE o DELETE a tablas permanentes.
  2. No determinismo: Antiguamente no podías usar GETDATE() o NEWID() dentro de una función porque devuelven valores distintos cada vez. (En versiones modernas se ha relajado un poco, pero sigue siendo una limitación conceptual).
  3. Gestión de errores: No puedes usar TRY...CATCH dentro de una función. Si falla, la consulta entera se detiene.

¿Función o procedimiento almacenado?

Aunque se parecen, tienen propósitos y reglas muy diferentes.

CaracterísticaProcedimiento Almacenado (SP)Función (UDF)
ObjetivoEjecutar una lógica de negocio completa (Proceso).Calcular y transformar valores.
InvocaciónCon EXEC (independiente).Dentro de un SELECT, WHERE, JOIN.
RetornoPuede no devolver nada, devolver parámetros OUTPUT o múltiples tablas.Debe devolver un valor (escalar o tabla).
Modificar DatosSÍ. Puede hacer INSERT, UPDATE, DELETE.NO. Solo puede leer. No puede modificar tablas base.
Try/CatchPermitido.No permitido dentro de la función.

En resumen

  • ¿Necesitas modificar datos (INSERT/UPDATE)? Usa un Procedimiento.
  • ¿Necesitas calcular algo para mostrarlo en una columna o filtrar? Usa una Función.