jueves, 8 de diciembre de 2011

Construir SQL dinámicos en PostgreSQL con PL/pgSQL

A veces queremos ejecutar un SQL dentro de una función (como en un trigger) en el que los nombres de los campos o de la tabla a consultar varian, es decir que es dinámico.

Si estamos usando el lenguaje procedimental de PostgreSQL (PL/pgSQL), esto puede hacerse a través de concatenación de cadenas de texto.

Para el ejemplo, supongamos que queremos una función que nos genere el código siguiente para un campo y tenemos la misma estructura para diferentes tablas, así que queremos que la función sea reutilizable. El código es muy sencillo: tomar el último valor para el campo, sumarle 1 y devolver el resultado:

CREATE OR REPLACE FUNCTION generar_siguiente_codigo(tabla_nombre varchar, col1_nombre varchar, col2_nombre varchar, col1_valor int) RETURNS smallint AS $$
DECLARE
max_cod SMALLINT;
sig_cod SMALLINT;
BEGIN

EXECUTE 'SELECT MAX('|| col2_nombre ||') FROM '|| tabla_nombre::regclass ||' WHERE '|| col1_nombre ||' = $1'
INTO max_cod
USING col1_valor;

IF max_cod IS NULL THEN
max_cod := 0;
END IF;

sig_cod := max_cod + 1;

RETURN sig_cod;
END
$$
LANGUAGE 'plpgsql';

El comando EXECUTE es el que nos permite ejecutar el SQL creado, que es sólo una concatenación de textos mediante el operador ||. Es necesario usar el identificador regclass para el nombre de las tablas o el SQL no funcionará.

Y eso es todo.