As funções escritas em PL/pgSQL são definidas para o servidor executando o comando CREATE FUNCTION. Este comando normalmente se parece com, digamos,
CREATE FUNCTION algumafunc(integer, text) RETURNS integer
AS 'texto do corpo da função'
LANGUAGE plpgsql;
O corpo da função é apenas um literal cadeia de caracteres no
que diz respeito a CREATE FUNCTION.
Geralmente, é útil usar delimitação por cifrão
(veja Constantes do tipo cadeia de caracteres delimitadas por cifrão) para escrever
o corpo da função, em vez de usar a sintaxe normal de apóstrofos.
Sem a delimitação por cifrão, quaisquer apóstrofos ou contrabarras
no corpo da função devem receber escape dobrando-os.
Quase todos os exemplos neste capítulo usam delimitação por cifrão
para seus corpos de função.
PL/pgSQL é uma linguagem estruturada em blocos. O texto completo do corpo de uma função deve ser um bloco. Um bloco é definido como:
[ <<rótulo>> ] [ DECLAREdeclarações] BEGINinstruçõesEND [rótulo];
Cada declaração e cada instrução no interior de um bloco é encerrada
por ponto e vírgula.
Um bloco que aparece dentro de outro bloco deve ter um ponto e
vírgula após o END, conforme mostrado acima;
entretanto, o END final que conclui o corpo da
função não requer ponto e vírgula.
Um erro comum é escrever ponto e vírgula logo após o
BEGIN.
Isto está errado, resultando em erro de sintaxe.
O rótulo só é necessário se for desejado
identificar o bloco para uso em uma instrução EXIT,
ou para qualificar os nomes das variáveis declaradas no bloco.
Se for fornecido um rótulo após o END,
este rótulo deverá corresponder ao rótulo no início do bloco.
Não faz diferença usar letras maiúsculas ou minúsculas nas palavras-chave. Os identificadores são implicitamente convertidos em letras minúsculas, a menos que sejam colocados entre aspas, assim como nos comandos SQL comuns.
Os comentários funcionam da mesma forma no código
PL/pgSQL que no SQL
comum.
Dois hifens (--) iniciam um comentário, que se
estende até o final da linha.
O /* inicia um bloco de comentários, que se
estende até a ocorrência correspondente de */.
Os blocos de comentários podem ser aninhados.
Toda instrução na seção de instrução de um bloco pode ser um sub-bloco. Os sub-blocos podem ser usados para agrupamento lógico, ou para criar variáveis locais em um pequeno grupo de instruções. As variáveis declaradas em um sub-bloco escondem quaisquer variáveis com nomes idênticos de blocos externos durante a execução do sub-bloco; mas é possível acessar as variáveis externas assim mesmo, qualificando seus nomes com o rótulo do bloco externo. Por exemplo:
CREATE FUNCTION algumafunc() RETURNS integer AS $$
<< blocoexterno >>
DECLARE
quantidade integer := 30;
BEGIN
RAISE NOTICE 'A quantidade aqui é %', quantidade; -- Mostra 30
quantidade := 50;
--
-- Criar um sub-bloco
--
DECLARE
quantidade integer := 80;
BEGIN
RAISE NOTICE 'A quantidade aqui é %', quantidade; -- Mostra 80
RAISE NOTICE 'A quantidade lá fora é %', blocoexterno.quantidade; -- Mostra 50
END;
RAISE NOTICE 'A quantidade aqui é %', quantidade; -- Mostra 50
RETURN quantidade;
END;
$$ LANGUAGE plpgsql;
Na verdade, existe um “bloco externo” oculto
envolvendo o corpo de qualquer função
PL/pgSQL.
Este bloco fornece as declarações dos parâmetros da função
(se houver), bem como algumas variáveis especiais como
FOUND
(veja Obtenção do status do resultado).
O bloco externo é rotulado com o nome da função, significando
que parâmetros e variáveis especiais podem ser qualificados com
o nome da função.
É importante não confundir o uso de
BEGIN/END para agrupar
instruções no PL/pgSQL com os comandos
SQL de mesmo nome usados para controlar
transação.
Os BEGIN/END do
PL/pgSQL são apenas para agrupamento;
não iniciam ou terminam uma transação.
Veja Gerenciamento de transação para obter
informações sobre como gerenciar transações no
PL/pgSQL.
Além disso, um bloco contendo a cláusula EXCEPTION
forma de fato uma subtransação que pode ser desfeita sem afetar
a transação externa. Para obter mais informações veja
Captura de erros.