CodeGym /Cursos /SQL SELF /Creando funciones simples: CREATE FUNCTION

Creando funciones simples: CREATE FUNCTION

SQL SELF
Nivel 50 , Lección 0
Disponible

Creando funciones simples: CREATE FUNCTION

En PostgreSQL las funciones son una herramienta potente que te permite automatizar tareas, crear lógica de negocio y darle más inteligencia al servidor. Piensa en las funciones como mini-programas que se ejecutan dentro de la base de datos. Son útiles para:

  • Reutilizar código. Si repites las mismas consultas varias veces, mételas en una función y llámalas cuando las necesites.
  • Automatizar tareas. Por ejemplo, si necesitas calcular el sueldo de los empleados según sus horas trabajadas. Una función lo hace de lujo.
  • Encapsular lógica. Permite dejar los cálculos complicados en el servidor, así los clientes no se rompen la cabeza con consultas SQL.

Sintaxis general de CREATE FUNCTION

Así se ve la estructura general para crear una función:

CREATE FUNCTION function_name(parameters) RETURNS return_type AS $$
BEGIN
    -- Cuerpo de la función (lógica)
    RETURN resultado;
END;
$$ LANGUAGE plpgsql;

Vamos a ver las partes principales:

CREATE FUNCTION function_name(parameters):

En esta línea ponemos el nombre de la función function_name y los parámetros (si hacen falta).

Los parámetros pueden tener nombre y tipo de dato: my_param INTEGER, another_param TEXT.

RETURNS return_type:

Indicamos qué va a devolver nuestra función: un solo valor (INTEGER, TEXT, etc.) o un conjunto de datos (TABLE, RECORD).

BEGIN ... END:

Entre estas palabras clave está el "cuerpo" de la función, donde pasa toda la magia.

RETURN resultado:

Devuelve el resultado de la función. Ojo: el tipo del resultado tiene que ser igual al que pusiste en RETURNS.

LANGUAGE plpgsql:

Indicamos que usamos el lenguaje PL/pgSQL. PostgreSQL soporta otros lenguajes, pero ahora nos interesa este.

Ejemplo simple: sumar dos números

Vamos a crear una función que devuelve la suma de dos números enteros.

CREATE FUNCTION add_numbers(a INT, b INT) RETURNS INT AS $$
BEGIN
    RETURN a + b;
END;
$$ LANGUAGE plpgsql;

Ahora la llamamos:

SELECT add_numbers(5, 7); -- Resultado: 12

¿Qué pasa aquí?

  • La función recibe dos parámetros a y b de tipo INT.
  • Dentro de la función simplemente los sumamos (a + b) y devolvemos el resultado.
  • ¡Así de fácil, como una calculadora!

Ejemplo usando variables

Imagina que tenemos una base de datos de una universidad y queremos saber cuántos estudiantes están registrados.

Creamos la función:

CREATE FUNCTION count_students() RETURNS INT AS $$
DECLARE
    total INT; -- Declaramos una variable para guardar el resultado
BEGIN
    SELECT COUNT(*) INTO total FROM students; -- Contamos las filas en la tabla
    RETURN total; -- Devolvemos el resultado
END;
$$ LANGUAGE plpgsql;

Llamada a la función:

SELECT count_students(); -- Supongamos, resultado: 120

Aquí vemos:

  • Uso de la variable total para guardar el resultado de la consulta SQL.
  • El comando SELECT ... INTO mete el resultado de la consulta en la variable.

Este enfoque es muy útil si necesitas procesar los datos antes de devolverlos.

Devolver varios valores: RETURNS TABLE

En el ejemplo anterior solo devolvíamos un valor. Pero ¿y si nuestra función tiene que devolver un conjunto de datos, como una lista de estudiantes? Aquí es donde RETURNS TABLE es útil.

Ejemplo:

CREATE FUNCTION get_students() RETURNS TABLE(id INT, name TEXT) AS $$
BEGIN
    RETURN QUERY SELECT id, name FROM students;
END;
$$ LANGUAGE plpgsql;

Llamada a la función:

SELECT * FROM get_students();

Posible resultado:

id name
1 Alice
2 Bob
3 Charlie

La utilidad de RETURN QUERY para ejecutar consultas dentro de la función

RETURN QUERY nos permite devolver el resultado de una consulta SQL directamente desde la función. Así nos ahorramos pasos intermedios y las funciones quedan más simples.

Vamos a crear una función que solo devuelve los estudiantes que están activos:

CREATE FUNCTION get_active_students() RETURNS TABLE(id INT, name TEXT) AS $$
BEGIN
    RETURN QUERY SELECT id, name FROM students WHERE active = TRUE;
END;
$$ LANGUAGE plpgsql;

Antes de llamar a la función get_active_students(), hay que crear la tabla students y llenarla con datos de prueba. Así se hace:

-- Creamos la tabla de estudiantes
CREATE TABLE students (
    id SERIAL PRIMARY KEY,
    name TEXT NOT NULL,
    active BOOLEAN DEFAULT TRUE
);

-- Añadimos algunos registros
INSERT INTO students (name, active) VALUES
('Alice', FALSE),
('Bob', TRUE),
('Charlie', TRUE),
('Dana', FALSE);

Tabla:

id name active
1 Alice false
2 Bob true
3 Charlie true
4 Dana false

Ahora la llamada:

SELECT * FROM get_active_students();

Resultado:

id name
2 Bob
3 Charlie

Comprobando la validez de los datos antes de ejecutar

Las funciones pueden tener comprobaciones IF para asegurarse de que los datos son correctos. Por ejemplo, podemos crear una función para pasar a un estudiante al siguiente curso solo si ha aprobado todos los exámenes.

Ejemplo:

CREATE FUNCTION promote_student(student_id INT) RETURNS TEXT AS $$
DECLARE
    passed_exams INT;
BEGIN
    -- Contamos el número de exámenes aprobados por el estudiante
    SELECT COUNT(*) INTO passed_exams
    FROM exams
    WHERE student_id = promote_student.student_id AND status = 'aprobado';

    -- Comprobamos la condición
    IF passed_exams < 5 THEN
        RETURN 'El estudiante no ha aprobado suficientes exámenes';
    END IF;

    -- Actualizamos el curso del estudiante
    UPDATE students
    SET course = course + 1
    WHERE id = promote_student.student_id;

    RETURN '¡Estudiante promovido!';
END;
$$ LANGUAGE plpgsql;

Errores típicos al crear funciones

Falta el tipo de resultado. PostgreSQL siempre exige que indiques qué va a devolver la función. Por ejemplo:

CREATE FUNCTION fail() AS $$ -- Error: falta RETURNS
BEGIN
    RETURN 1;
END;
$$ LANGUAGE plpgsql;

Solución:

CREATE FUNCTION succeed() RETURNS INT AS $$
BEGIN
    RETURN 1;
END;
$$ LANGUAGE plpgsql;

Tipo de resultado incorrecto. Si pones RETURNS INT, tienes que devolver un número. Intentar devolver una cadena en ese caso es mala idea.

Error en las consultas SQL dentro de la función. Siempre prueba tus consultas antes de usarlas en funciones. Mejor testéalas "a mano" con psql o pgAdmin.

Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION