Modelado físico avanzado relacional de bases de datos

Las funciones en bases de datos permiten encapsular lógica y devolver un resultado. Son útiles cuando necesitamos calcular valores, validar datos o reutilizar código en consultas.


1. Diferencias entre Procedimientos y Funciones

Aunque procedimientos y funciones pueden parecer similares, tienen diferencias clave:

CaracterísticaProcedimientosFunciones
Devuelve valoresOpcionalSiempre devuelve un valor
Uso en SELECT❌ No✅ Sí
Modifica datos (INSERT, UPDATE, DELETE)✅ Sí❌ No
Se usa con CALL o EXEC✅ Sí❌ No

2. Creación de Funciones en Bases de Datos

Las funciones pueden devolver:

  • Un solo valor (escalar)
  • Una tabla completa (tabla)

📌 Ejemplo: Función Escalar

Esta función recibe un ID de empleado y devuelve su salario.

1DELIMITER //
2
3CREATE FUNCTION ObtenerSalario(emp_id INT) RETURNS DECIMAL(10,2)
4DETERMINISTIC
5BEGIN
6    DECLARE salario DECIMAL(10,2);
7    SELECT sueldo INTO salario FROM empleados WHERE id = emp_id;
8    RETURN salario;
9END //
10
11DELIMITER ;
12
13-- La palabra clave DETERMINISTIC en MySQL se utiliza al definir funciones o procedimientos almacenados para indicar que el resultado de la función será siempre el mismo
14
15-- Uso:
16SELECT ObtenerSalario(3);

3. Funciones que Devuelven una Tabla

A veces necesitamos que una función devuelva varias filas en lugar de un solo valor.

📌 Ejemplo: Función que Devuelve Empleados de un Departamento

1-- ⚠️ **MySQL no soporta directamente funciones que devuelvan tablas**, se recomienda usar procedimientos almacenados en su lugar.

4. Control de Flujo en Funciones

Podemos usar estructuras como IF, CASE, LOOP, etc.

📌 Ejemplo: Función que Evalúa el Nivel de Salario

Esta función clasifica los salarios en Bajo, Medio o Alto.

1DELIMITER //
2
3CREATE FUNCTION ClasificarSalario(sueldo DECIMAL(10,2)) RETURNS VARCHAR(20)
4DETERMINISTIC
5BEGIN
6    RETURN CASE 
7        WHEN sueldo < 2000 THEN 'Bajo'
8        WHEN sueldo BETWEEN 2000 AND 5000 THEN 'Medio'
9        ELSE 'Alto'
10    END;
11END //
12
13DELIMITER ;
14
15-- Uso:
16SELECT ClasificarSalario(3000);

5. Manejo de Errores en Funciones

Podemos capturar errores para evitar fallos en la ejecución.

1DELIMITER //
2
3CREATE FUNCTION DivisionSegura(a NUMERIC, b NUMERIC)
4RETURNS NUMERIC
5DETERMINISTIC
6BEGIN
7    IF b = 0 THEN
8        RETURN NULL;
9    ELSE
10        RETURN a / b;
11    END IF;
12END;
13//
14
15DELIMITER ;
16
17-- Uso:
18SELECT DivisionSegura(10, 0);

6. Optimización de Funciones

Para mejorar el rendimiento: ✅ Usar índices en las columnas consultadas.
Evitar cursores cuando no sean necesarios.
Usar funciones inmutables (DETERMINISTIC en MySQL, STABLE en PostgreSQL).

Ejemplo de optimización:

1SELECT nombre FROM empleados WHERE departamento_id = 3 LIMIT 10;

7. Ejemplo Completo

Vamos a crear una función que calcula el descuento de un producto según su precio.

1DELIMITER //
2
3CREATE FUNCTION CalcularDescuento(precio DECIMAL(10,2)) RETURNS DECIMAL(10,2)
4DETERMINISTIC
5BEGIN
6    RETURN precio * 0.90; -- Aplica 10% de descuento
7END //
8
9DELIMITER ;
10
11-- Uso:
12SELECT CalcularDescuento(100);

DETERMINISTIC vs NOT DETERMINISTIC

La palabra clave DETERMINISTIC en MySQL se utiliza al definir funciones o procedimientos almacenados para indicar que el resultado de la función será siempre el mismo, dado un conjunto específico de parámetros de entrada. En otras palabras, una función determinista siempre devolverá el mismo resultado para los mismos valores de entrada.

¿Qué significa y cómo se utiliza?

  • DETERMINISTIC: Significa que la función no depende de factores externos, como la fecha y hora actuales, el estado del sistema o cualquier dato que pueda cambiar entre ejecuciones. El valor de retorno de la función será predecible y consistente cuando se le pase el mismo conjunto de parámetros.

  • NOT DETERMINISTIC: Si una función puede devolver resultados diferentes con el mismo conjunto de parámetros (por ejemplo, si depende de la hora del sistema o de variables globales que cambian), se debe usar NOT DETERMINISTIC. Esto es útil cuando se sabe que la función puede generar resultados variables incluso para los mismos parámetros.

Ejemplo:

Función Determinista

1CREATE FUNCTION CalcularAreaRectangulo(base INT, altura INT)
2RETURNS INT
3DETERMINISTIC
4BEGIN
5    RETURN base * altura;
6END;
  • En este caso, la función CalcularAreaRectangulo es determinista porque, para cualquier par de valores base y altura, el resultado será siempre el mismo (el área del rectángulo).

Función No Determinista

1CREATE FUNCTION ObtenerFechaActual()
2RETURNS DATETIME
3NOT DETERMINISTIC
4BEGIN
5    RETURN NOW();
6END;