Las funciones escritas en PL/pgSQL se definen en el servidor ejecutando comandos CREATE FUNCTION. Dicho comando normalmente se vería, por ejemplo, como
CREATE FUNCTION somefunc(integer, text) RETURNS integer
AS 'cuerpo de la función'
LANGUAGE plpgsql;
El cuerpo de la función es simplemente una cadena literal en lo que respecta a
CREATE FUNCTION. A menudo es útil usar comillas de dólar
(consulta la Section 4.1.2.4) para escribir el cuerpo de
la función, en lugar de la sintaxis normal de comillas simples. Sin comillas de dólar,
cualquier comilla simple o barra invertida en el cuerpo de la función debe escaparse
duplicándola. Casi todos los ejemplos de este capítulo utilizan literales delimitados
por comillas de dólar para los cuerpos de sus funciones.
PL/pgSQL es un lenguaje estructurado en bloques. El texto completo del cuerpo de una función debe ser un bloque. Un bloque se define como:
[ <<etiqueta>> ] [ DECLAREdeclaraciones] BEGINinstruccionesEND [etiqueta];
Cada declaración y cada instrucción dentro de un bloque termina
con un punto y coma. Un bloque que aparece dentro de otro bloque debe
tener un punto y coma después de END, como se muestra arriba;
sin embargo, el END final que
concluye el cuerpo de una función no requiere un punto y coma.
Un error común es escribir un punto y coma inmediatamente después de
BEGIN. Esto es incorrecto y provocará un error de sintaxis.
Una etiqueta solo es necesaria si deseas
identificar el bloque para usarlo
en una instrucción EXIT, o para calificar los nombres de las
variables declaradas en el bloque. Si se proporciona una etiqueta después de
END, esta debe coincidir con la etiqueta al comienzo del bloque.
Todas las palabras clave son insensibles a mayúsculas y minúsculas. Los identificadores se convierten implícitamente a minúsculas a menos que estén entre comillas dobles, al igual que en los comandos SQL ordinarios.
Los comentarios funcionan de la misma manera en el código de PL/pgSQL que en
el SQL ordinario. Un guion doble (--) inicia un comentario
que se extiende hasta el final de la línea. Un /* inicia un
comentario de bloque que se extiende hasta la aparición correspondiente de
*/. Los comentarios de bloque se pueden anidar.
Cualquier instrucción en la sección de instrucciones de un bloque puede ser un subbloque. Los subbloques se pueden usar para el agrupamiento lógico o para localizar variables a un grupo pequeño de instrucciones. Las variables declaradas en un subblock ocultan las variables de nombres similares de los bloques externos durante la duración del subbloque; pero de todos modos puedes acceder a las variables externas si calificas sus nombres con la etiqueta de su bloque. Por ejemplo:
CREATE FUNCTION somefunc() RETURNS integer AS $$
<< outerblock >>
DECLARE
quantity integer := 30;
BEGIN
RAISE NOTICE 'La cantidad aquí es %', quantity; -- Imprime 30
quantity := 50;
--
-- Crear un subbloque
--
DECLARE
quantity integer := 80;
BEGIN
RAISE NOTICE 'La cantidad aquí es %', quantity; -- Imprime 80
RAISE NOTICE 'La cantidad externa aquí es %', outerblock.quantity; -- Imprime 50
END;
RAISE NOTICE 'La cantidad aquí es %', quantity; -- Imprime 50
RETURN quantity;
END;
$$ LANGUAGE plpgsql;
En realidad, existe un “bloque externo” oculto que rodea el cuerpo
de cualquier función de PL/pgSQL. Este bloque proporciona las
declaraciones de los parámetros de la función (si los hay), así como algunas
variables especiales como FOUND (consulta la
Section 41.5.5). El bloque externo está
etiquetado con el nombre de la función, lo que significa que los parámetros y las variables
especiales se pueden calificar con el nombre de la función.
Es importante no confundir el uso de
BEGIN/END para agrupar instrucciones en
PL/pgSQL con los comandos SQL del mismo nombre
para el control de transacciones. Los BEGIN/END
de PL/pgSQL son solo para agrupar; no inician ni terminan una transacción.
Consulta la Section 41.8 para obtener información sobre la gestión de
transacciones en PL/pgSQL.
Además, un bloque que contiene una cláusula EXCEPTION forma efectivamente
una subtransacción que se puede revertir sin afectar a la transacción externa.
Para obtener más información al respecto, consulta la Section 41.6.8.