CodeGym /Cursos /SQL SELF /Control de ejecución de funciones: PERFORM

Control de ejecución de funciones: PERFORM

SQL SELF
Nivel 55 , Lección 3
Disponible

PERFORM en el mundo de PostgreSQL es como ese héroe silencioso y duro que llega, hace su trabajo y desaparece sin dejar rastro en forma de datos devueltos. Este comando se usa cuando quieres ejecutar una consulta SQL dentro de una función PL/pgSQL, pero no necesitas procesar ni guardar el resultado. El objetivo principal de PERFORM es lanzar la consulta para que pase algo, como modificar datos o llamar otra función, y no para obtener un resultado.

PERFORM se usa cuando el resultado de la consulta no nos interesa. A diferencia de un SELECT normal, que espera que hagas algo con el resultado, PERFORM simplemente ejecuta la consulta y sigue adelante en silencio. Esto es súper útil si llamas a una función solo por su efecto, no por lo que devuelve. Por ejemplo, para escribir algo en el log. Así el código es más simple y claro: menos cosas de relleno, más sentido.

Ejemplos de uso de PERFORM

Llamada a funciones

Vamos a ver un ejemplo real. Imagina que tienes una función log_action que guarda información sobre las acciones del usuario en los logs. Esta función no devuelve nada, y solo queremos que se ejecute. Así es como se hace con PERFORM:

CREATE OR REPLACE FUNCTION log_action(user_id INT, action TEXT) RETURNS VOID AS $$
BEGIN
    INSERT INTO logs (user_id, action, log_time)
    VALUES (user_id, action, NOW());
END;
$$ LANGUAGE plpgsql;

-- Ahora usamos PERFORM para llamar a esta función:
PERFORM log_action(5, 'Usuario inició sesión');

¿Qué pasa aquí? El comando PERFORM llama a la función log_action, que mete un registro en la tabla logs. Ojo: el resultado de la función se ignora. La usamos solo por su efecto, no por lo que devuelve.

Actualización de datos

A veces PERFORM es útil cuando necesitas ejecutar una consulta para cambiar datos sin preocuparte por el resultado. Por ejemplo, vamos a actualizar el estado de un pedido en la tabla orders.

CREATE OR REPLACE FUNCTION update_order_status(order_id INT, new_status TEXT) RETURNS VOID AS $$
BEGIN
    UPDATE orders
    SET status = new_status
    WHERE id = order_id;
END;
$$ LANGUAGE plpgsql;

-- Usamos PERFORM para llamar a esta función:
PERFORM update_order_status(101, 'Enviado');

Aquí update_order_status actualiza el estado del pedido con id 101. No nos importa el resultado de la consulta SQL dentro de la función, así que PERFORM es la opción perfecta.

Ejecución de operaciones auxiliares

A veces las funciones tienen mini-operaciones, como lógica "auxiliar" que ayuda a terminar un proceso complicado. Por ejemplo, queremos limpiar la caché después de actualizar una tabla:

CREATE OR REPLACE FUNCTION clear_cache() RETURNS VOID AS $$
BEGIN
    DELETE FROM cache_table;
END;
$$ LANGUAGE plpgsql;

-- La llamamos en otra función:
CREATE OR REPLACE FUNCTION update_product(product_id INT, new_price NUMERIC) RETURNS VOID AS $$
BEGIN
    UPDATE products
    SET price = new_price
    WHERE id = product_id;

    -- Limpiamos la caché después de cambiar los datos:
    PERFORM clear_cache();
END;
$$ LANGUAGE plpgsql;

Aquí está la magia: puedes ejecutar acciones en secuencia usando PERFORM para llamar funciones cuyo resultado no te importa para nada.

Ejercicios prácticos

Vamos a ver algunos ejemplos de cómo PERFORM puede hacerte la vida más fácil como desarrollador.

Ejemplo 1: loguear las etapas de una procedure

Imagina que tienes un procedure complicado para procesar pagos y necesitas registrar cada etapa en el log. Podemos definir una función log_stage para guardar la info y luego usar PERFORM:

CREATE OR REPLACE FUNCTION log_stage(stage_name TEXT) RETURNS VOID AS $$
BEGIN
    INSERT INTO process_logs(stage, log_time)
    VALUES (stage_name, NOW());
END;
$$ LANGUAGE plpgsql;

-- Y aquí va el procedure:
CREATE OR REPLACE FUNCTION process_payment(payment_id INT) RETURNS VOID AS $$
BEGIN
    -- Loguear el inicio
    PERFORM log_stage('Inicio del procesamiento de pago');

    -- Primer paso
    UPDATE payments
    SET status = 'Procesando'
    WHERE id = payment_id;

    PERFORM log_stage('Estado del pago actualizado');

    -- Paso final
    UPDATE payments
    SET status = 'Completado'
    WHERE id = payment_id;

    PERFORM log_stage('Pago completado');
END;
$$ LANGUAGE plpgsql;

Aquí log_stage se llama con PERFORM para guardar el estado de ejecución en cada etapa del procedure. Así el código es más fácil de depurar.

Ejemplo 2: activar notificaciones

Imagina que tienes un sistema de notificaciones y necesitas enviar una notificación después de cada acción importante. PERFORM puede usarse para llamar a la función encargada de eso:

CREATE OR REPLACE FUNCTION send_notification(user_id INT, message TEXT) RETURNS VOID AS $$
BEGIN
    INSERT INTO notifications (user_id, message, created_at)
    VALUES (user_id, message, NOW());
END;
$$ LANGUAGE plpgsql;

-- Usamos en el procedure:
CREATE OR REPLACE FUNCTION complete_task(task_id INT) RETURNS VOID AS $$
DECLARE
    user_id INT;
BEGIN
    -- Obtener el autor de la tarea
    SELECT assigned_to INTO user_id
    FROM tasks
    WHERE id = task_id;

    -- Completar la tarea
    UPDATE tasks
    SET status = 'Completada'
    WHERE id = task_id;

    -- Enviar notificación
    PERFORM send_notification(user_id, 'Tu tarea ha sido completada');
END;
$$ LANGUAGE plpgsql;

Aquí PERFORM te permite centrarte solo en el efecto secundario —enviar la notificación— ignorando el resultado de la función.

Consejos útiles y errores típicos

Cuando uses PERFORM, hay que tener en cuenta algunas cosas. Por ejemplo, PERFORM no comprueba si la consulta devolvió datos. O sea, si el resultado de la función o consulta SQL es importante para la lógica, mejor usa SELECT INTO. Mira este ejemplo:

-- Error típico
PERFORM alguna_funcion_que_debe_devolver_valor();

-- Solución
SELECT alguna_funcion_que_debe_devolver_valor() INTO alguna_variable;

Otro error común es usar PERFORM donde realmente necesitas el resultado de la consulta, por ejemplo, para validar datos. En esos casos, claro, mejor obtener el resultado y comprobarlo.

En proyectos reales, el comando PERFORM ayuda a que las funciones y procedures sean más simples, fáciles de leer y de depurar. Si lo combinas con logs (RAISE NOTICE) y funciones de diagnóstico de PostgreSQL como current_query(), se vuelve una herramienta clave para crear sistemas fiables, controlables y claros.

2
Tarea
SQL SELF, nivel 55, lección 3
Bloqueada
Llamada a una función de registro usando `PERFORM`
Llamada a una función de registro usando `PERFORM`
Comentarios
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION