Cuando escribes funciones en PostgreSQL, una de las primeras cosas que tienes que entender es cómo devolver el resultado. A veces solo necesitas devolver un número. Otras veces — una tabla entera. Y a veces — incluso varios conjuntos de datos. En esta sección vamos a ver todas las opciones principales: desde el más simple RETURN hasta RETURN QUERY, RETURNS TABLE y SETOF.
Un resultado: RETURN
Si tu función tiene que devolver solo un valor — por ejemplo, una suma o la cantidad de filas — usa el clásico RETURN.
CREATE FUNCTION count_students() RETURNS INT AS $$
DECLARE
total INT;
BEGIN
SELECT COUNT(*) INTO total FROM students;
RETURN total;
END;
$$ LANGUAGE plpgsql;
Cuando creas una función en PL/pgSQL, tienes que indicar qué devuelve. Esto va con la palabra clave RETURNS, que define el "formato" del resultado que devuelve la función. Así que si quieres devolver un número, un texto o una tabla de datos — todo eso tienes que ponerlo en la línea con RETURNS.
Un ejemplo sencillo:
CREATE FUNCTION add_numbers(a INT, b INT) RETURNS INT AS $$
BEGIN
RETURN a + b;
END;
$$ LANGUAGE plpgsql;
Aquí la palabra clave RETURNS INT indica que la función devuelve un número.
Devolver un solo valor
Vamos a empezar por lo más simple — una función que devuelve un solo valor. Por ejemplo, una función que cuenta la cantidad de estudiantes en la tabla students:
CREATE FUNCTION count_students() RETURNS INT AS $$
DECLARE
total INT;
BEGIN
SELECT COUNT(*) INTO total FROM students; -- Guardamos el resultado de la consulta en la variable total
RETURN total; -- Devolvemos el resultado
END;
$$ LANGUAGE plpgsql;
Ahora podemos llamar a esta función:
SELECT count_students(); -- Devuelve la cantidad de estudiantes
Devolver varios valores usando RETURNS TABLE
A veces necesitas devolver no solo un valor, sino un conjunto de registros. Por ejemplo, la lista de todos los estudiantes con sus nombres e identificadores. Para eso se usa la construcción RETURNS TABLE.
CREATE FUNCTION get_students() RETURNS TABLE(id INT, name TEXT) AS $$
BEGIN
RETURN QUERY SELECT id, name FROM students; -- Devolvemos el resultado de la consulta como tabla
END;
$$ LANGUAGE plpgsql;
Ahora podemos llamar a esta función:
SELECT * FROM get_students(); -- Devuelve la tabla con todos los estudiantes
Fíjate en las palabras clave RETURNS TABLE. Indican que la función devuelve una tabla con las columnas indicadas (id y name en este caso).
Usando RETURN QUERY
Seguro que ya te gustó nuestro ejemplo de arriba. Pero aquí va otro detalle: RETURN QUERY — es la varita mágica de PL/pgSQL que te permite devolver datos directamente desde una consulta. Con ella puedes devolver tanto el resultado de toda una consulta como un subconjunto.
Por ejemplo, queremos devolver todos los estudiantes que están estudiando activamente (su estado en la base de datos está marcado como active = TRUE):
CREATE FUNCTION get_active_students() RETURNS TABLE(id INT, name TEXT) AS $$
BEGIN
RETURN QUERY
SELECT id, name
FROM students
WHERE active = TRUE; -- Devolvemos solo los estudiantes activos
END;
$$ LANGUAGE plpgsql;
Ahora podemos llamar a la función y obtener los datos de los estudiantes activos:
SELECT * FROM get_active_students();
Devolver varias filas sin RETURNS TABLE
En algunos casos puedes querer devolver filas de datos sin usar RETURNS TABLE. Para eso puedes usar el tipo de datos SETOF. Esto te permite devolver filas de datos con la misma estructura. Por ejemplo:
CREATE FUNCTION get_student_names() RETURNS SETOF TEXT AS $$
BEGIN
RETURN QUERY
SELECT name
FROM students;
END;
$$ LANGUAGE plpgsql;
Esta función devuelve solo la lista de nombres de los estudiantes:
SELECT * FROM get_student_names();
Devolver valores según los datos de entrada
Las funciones no siempre devuelven solo resultados estáticos. Pueden usar parámetros para cambiar los resultados dinámicamente.
Aquí tienes un ejemplo de cómo devolver datos por el identificador del estudiante
CREATE FUNCTION get_student_by_id(student_id INT) RETURNS TABLE(id INT, name TEXT) AS $$
BEGIN
RETURN QUERY
SELECT id, name
FROM students
WHERE id = student_id; -- Usamos el parámetro student_id
END;
$$ LANGUAGE plpgsql;
Ahora puedes pedir información sobre un estudiante concreto:
SELECT * FROM get_student_by_id(3); -- Devuelve los datos del estudiante con ID = 3
Devolver datos complejos (varios conjuntos)
A veces los datos son tan complejos que hay que devolver varios conjuntos. Para eso puedes usar cursores. Por ejemplo, si quieres dar dos conjuntos de datos desde una función — la lista de estudiantes activos y la de inactivos.
CREATE FUNCTION get_students_status() RETURNS SETOF RECORD AS $$
BEGIN
RETURN QUERY
SELECT id, name, 'activo' AS status
FROM students
WHERE active = TRUE;
RETURN QUERY
SELECT id, name, 'inactivo' AS status
FROM students
WHERE active = FALSE;
END;
$$ LANGUAGE plpgsql;
Ahora puedes obtener ambos conjuntos de datos:
SELECT * FROM get_students_status();
Errores típicos al trabajar con RETURNS
No indicar el tipo de retorno: Si no indicas qué devuelve la función, PostgreSQL te dará un error. Por ejemplo:
CREATE FUNCTION no_return_type() AS $$ -- Error, no se indicó RETURNS
BEGIN
RETURN 1;
END;
$$ LANGUAGE plpgsql;
No coinciden los tipos de datos: asegúrate de que los valores que devuelves coinciden con los tipos declarados. Por ejemplo, si pusiste que devuelves INT, no intentes devolver una cadena.
Olvidar usar RETURN QUERY: si te olvidas de usar RETURN QUERY para ejecutar una consulta compleja, la función simplemente no devolverá nada.
Devolver varios valores de forma incorrecta: si devuelves una fila de datos pero te olvidas de usar SETOF o TABLE, PostgreSQL te dará un error.
GO TO FULL VERSION