PL-PGSQL

PL/pgSQL (Procedural Language/PostgreSQL Structured Query Language) es un lenguaje imperativo provisto por el gestor de base de datos PostgreSQL. Permite ejecutar comandos SQL mediante un lenguaje de sentencias imperativas y uso de funciones, dando mucho más control automático que las sentencias SQL básicas.

Desde PL/pgSQL se pueden realizar cálculos complejos y crear nuevos tipos de datos de usuario. Como un verdadero lenguaje de programación, dispone de estructuras de control repetitivas y condicionales, además de la posibilidad de creación de funciones que pueden ser llamadas en sentencias SQL normales o ejecutadas en eventos de tipo disparador (trigger).

Una de las principales ventajas de ejecutar programación en el servidor de base de datos es que las consultas y el resultado no tienen que ser transportadas entre el cliente y el servidor, ya que los datos residen en el propio servidor. Además, el gestor de base de datos puede planificar optimizaciones en la ejecución de la búsqueda y actualización de datos.

Wikipedia

Las funciones escritas en PL/pgSQL aceptan argumentos y pueden devolver valores de tipo básico o de tipo complejo (por ejemplo, registros, vectores, conjuntos o incluso tablas), permitiéndose tipificación polimórfica para funciones abstractas o genéricas (referencia a variables de tipo objeto).

Propiedades de una función programada:
Parámetros

Ejercicio 1: Función que recibe parámetros y devuelve una operación realizada con ellos

primera(int a,int b)
DECLARE
    c int8;
BEGIN
    c=3000;
    return a+b+c;
END

Ejercicio 2: Función que utiliza datos provinientes de una consulta SQL

segunda()
DECLARE
    total int8;
BEGIN
    total=0;
    SELECT INTO total sum(salario) FROM templa;
    return total;
END

Ejercicio 3: Función que recibe un parámetro y realiza una consulta SQL con ese valor

tercera(ape character varying(50))
DECLARE
    n int8;
BEGIN
    n=0;
    SELECT INTO n salario FROM templa WHERE apellido=ape;
    return n;
END

SELECT tercera('Yarza') devuelve el sueldo de ese empleado

Ejercicio 4: Uso de la sentencia IF...THEN...ELSE...END

cuarta(int a)
BEGIN
    IF (a<10) THEN
       return 1;
    ELSE
       return 0;
    END IF;
END

Devuelve 0 ó 1 dependiendo de que el parámetro que reciba sea mayot o menor que 10

Ejercicio 5:

Se dispone de una tabla llamada resultados que contiene los resultados de partidos de voley. Esta tabla tiene la siguiente estructura:
Por ejemplo, 1-1-NUM-3-ALM-2, significa que el partido número 1, perteneciente a la primera jornada el Numancia ganó por 3 a 2 a Almería
Sabiendo que el sistema de puntuación de esta competición hace que se den 3 puntos a quien gana por 3-0 ó 3-1, 2 puntos a quien gana por 3-2, 1 punto a quien pierde por 2-3 y 0 puntos a quier pierde por 0-3 ó 1-3, realizar la función puntos() a la que se pasa el código de un equipo y devuelve los puntos conseguidos de acuerdo a sus resultados

puntos (e char(3))
DECLARE
    puntuacion_total int8;
    puntos int 8;
BEGIN
    puntuacion_total=0;

    -- Partidos que el equipo e ha jugado en casa
    SELECT count(*)*3 into puntos FROM partidos WHERE eq_local=e AND set_local=3 AND (set_visitante=0 OR set_visitante=1);
    puntuacion_total=puntuacion_total+puntos;
    SELECT count(*)*2 into puntos FROM partidos WHERE eq_local=e AND set_local=3 AND set_visitante=2;
    puntuacion_total=puntuacion_total+puntos;
    SELECT count(*)*1 into puntos FROM partidos WHERE eq_local=e AND set_local=2 AND set_visitante=3;
    puntuacion_total=puntuacion_total+puntos;

    -- Partidos que el equipo e ha jugado fuera
    SELECT count(*)*3 into puntos FROM partidos WHERE eq_visitante=e AND (set_local=0 OR set_local=1) AND set_visitante=3;
    puntuacion_total=puntuacion_total+puntos;
    SELECT count(*)*2 into puntos FROM partidos WHERE eq_visitante=e AND set_local=2 AND set_visitante=3;
    puntuacion_total=puntuacion_total+puntos;
    SELECT count(*)*1 into puntos FROM partidos WHERE eq_visitante=e AND set_local=3 AND set_visitante=2;
    puntuacion_total=puntuacion_total+puntos;

    return puntuacion_total;
END


Ejercicio 6: Función que maneja una matriz

DECLARE
    a integer[];
BEGIN
    a[0]=35;
    a[1]=44;
    return a;
END;

Funciones que recorren un resultset

La sintaxis para recorrer un resultset registro a registro es:

FOR reg IN sql LOOP
    // Acciones con el registro
END LOOP;
Ejemplo: supongamos que se dispone de una tabla que recoje los movimientos diarios de caja de una empresa y se desea que el campo saldo tenga actualizado su valor
DECLARE
    reg RECORD;
    valor double precision;
BEGIN
    valor=0;
    FOR reg IN SELECT id,ingreso,gasto FROM diario ORDER BY id LOOP
        if(reg.ingreso is not null) then
            valor=valor+reg.ingreso;
        end if;
        if(reg.gasto is not null) then
            valor=valor-reg.gasto;
        end if;
        UPDATE diario SET saldo=valor WHERE id=reg.id;
    END LOOP;
    return 1;
END;

Ejercicio de SQL en postgres
Ejercicio de funciones en postgres