Vamos a meternos más a fondo en PL/pgSQL y empezar a usarlo de forma más activa.
Bloque de código
Un bloque de código en PL/pgSQL es el elemento básico del lenguaje. Se puede decir que es el esqueleto sobre el que se apoyan nuestras funciones, procedimientos y toda esa magia. El bloque se encarga de ejecutar la lógica, manejar datos, gestionar errores, y todo eso en un solo "contenedor".
Los bloques de PL/pgSQL están estructurados y tienen tres partes principales:
DECLARE: declaración de variables (opcional).BEGIN ... END: el bloque principal donde va la lógica.EXCEPTION: manejo de errores (opcional).
Para los que les molan las analogías: imagina una receta de cocina. Aunque el texto de la receta puede empezar con la lista de ingredientes, la magia de verdad pasa en el proceso de cocinar. En términos de PL/pgSQL:
DECLARE— es la lista de ingredientes (variables).BEGIN ... END— es donde mezclas, fríes y hierves.EXCEPTION— es el plan B si algo se quema.
Sintaxis de un bloque PL/pgSQL
Primero vamos a ver la estructura general del bloque, como el "esqueleto". Luego le ponemos carne (o queso vegano, si prefieres) — la lógica concreta.
DO $$
DECLARE
-- Aquí se declaran las variables
student_count INT;
BEGIN
-- Aquí va la lógica
SELECT COUNT(*) INTO student_count FROM students;
RAISE NOTICE 'Número total de estudiantes: %', student_count;
EXCEPTION
-- Aquí se manejan los errores
WHEN OTHERS THEN
RAISE NOTICE 'Ocurrió un error.';
END;
$$;
Vamos a desglosar esto paso a paso.
DECLARE— aquí declaramos nuestras variables. Lo guay es que PL/pgSQL soporta casi todos los tipos de datos de PostgreSQL — desde el humildeINTEGERhasta el exótico JSONB. Para declarar una variable, tienes que poner su nombre, tipo de dato y, si quieres, un valor inicial.
Ejemplo:
DECLARE
student_name TEXT; -- Variable para el nombre del estudiante
course_count INT := 0; -- Valor inicial igual a 0
is_graduated BOOLEAN; -- Variable booleana
Ojo que las variables pueden tener inicialización (como course_count) o no.
BEGIN ... END— el bloque principal de ejecución.
Esta parte del bloque es la que ejecuta la lógica principal. Aquí puedes:
- Ejecutar consultas SQL (
SELECT,INSERT, etc.). - Manipular datos.
- Usar estructuras de control (
IF,LOOP, etc.). - Mostrar mensajes de depuración con
RAISE.
Ejemplo:
BEGIN
SELECT COUNT(*) INTO student_count FROM students;
IF student_count > 0 THEN
RAISE NOTICE '¡Tenemos estudiantes!';
ELSE
RAISE NOTICE 'No se encontraron estudiantes.';
END IF;
END;
EXCEPTION— manejo de errores (opcional).
Si durante la ejecución del bloque ocurre un error, la sección EXCEPTION te permite capturarlo y hacer algo útil — como mostrar un mensaje o ejecutar código alternativo.
Ejemplo:
BEGIN
SELECT COUNT(*) INTO student_count FROM non_existing_table; -- ¡Error!
EXCEPTION
WHEN OTHERS THEN
RAISE NOTICE '¡Ups, algo salió mal!';
END;
Ejemplo real: contar estudiantes
Ahora juntamos todas las partes en un ejemplo que puede servir en la vida real. Vamos a escribir un bloque PL/pgSQL que cuenta cuántos estudiantes hay en la tabla students y muestra un mensaje.
DO $$
DECLARE
total_students INT; -- Variable para guardar el número de estudiantes
BEGIN
-- Contamos el número de estudiantes
SELECT COUNT(*) INTO total_students FROM students;
-- Mostramos el mensaje con el resultado
RAISE NOTICE 'Número de estudiantes: %', total_students;
EXCEPTION
-- Manejamos posibles errores, por ejemplo, si la tabla no existe
WHEN OTHERS THEN
RAISE NOTICE 'Ocurrió un error al contar estudiantes.';
END;
$$;
Al ejecutar este bloque verás un mensaje en la consola. Por ejemplo: Número de estudiantes: 42.
Detalles sobre el uso de variables
Vamos a ver algunos puntos importantes:
Asignar valores a variables. Para meter datos en una variable, puedes usar el operador SELECT INTO:
SELECT COUNT(*) INTO total_students FROM students;
Inicialización de variables. Si no le das un valor a la variable al declararla, su valor por defecto será NULL.
Por ejemplo:
DECLARE
my_var INT; -- Valor NULL
Variables de tipo RECORD. Este es un tipo de variable universal donde puedes meter filas de una tabla. Ejemplo:
DECLARE
student RECORD;
BEGIN
SELECT * INTO student FROM students WHERE id = 1;
RAISE NOTICE 'Nombre del estudiante: %, Edad: %', student.name, student.age;
END;
Ejemplo: contar cursos de un estudiante
Ahora vamos con un ejercicio práctico: contar cuántos cursos tiene un estudiante y mostrar el resultado.
DO $$
DECLARE
student_id INT := 1; -- ID del estudiante
course_count INT; -- Variable para el número de cursos
BEGIN
-- Contamos el número de cursos
SELECT COUNT(*) INTO course_count
FROM enrollments
WHERE student_id = student_id;
-- Mostramos el mensaje
RAISE NOTICE 'El estudiante con ID % está inscrito en % cursos.', student_id, course_count;
EXCEPTION
WHEN OTHERS THEN
RAISE NOTICE 'Ocurrió un error al procesar el ID de estudiante %', student_id;
END;
$$;
Este bloque es flexible: puedes cambiar student_id para ver cuántos cursos tiene cada estudiante.
Errores y cómo evitarlos
Si el PL/pgSQL dentro de ti ya está saltando como un perrito caliente en el microondas, tranquilo, es normal. Al principio es fácil encontrarse con errores "típicos". Aquí tienes algunos ejemplos:
No declarar una variable. Si te olvidas de declarar una variable con DECLARE, PL/pgSQL te va a decir que la variable "no existe".
Intentar usar NULL como valor. Si declaraste una variable pero no le diste valor, será NULL. Esto puede causar comportamientos raros. Por ejemplo:
IF my_var = NULL THEN -- ¡NO funciona!
Usa IS NULL:
IF my_var IS NULL THEN
Mal uso de la sección EXCEPTION. A veces la peña captura todos los errores (WHEN OTHERS), pero no pone qué hacer. Esto puede ocultar el problema real. Mejor escribe un mensaje de error:
RAISE NOTICE 'Error: %', SQLERRM;
GO TO FULL VERSION