35.2. Dicas para desenvolvimento em PL/pgSQL

PostgreSQL 14.5: Dicas para desenvolver em PL/pgSQL

Uma boa maneira de desenvolver em PL/pgSQL é utilizar o editor de texto preferido para criar as funções e, em outra janela, utilizar o psql para carregar e testar as funções desenvolvidas. Se estiver sendo feito desta maneira, é uma boa idéia escrever a função utilizando CREATE OR REPLACE FUNCTION. Fazendo assim, basta recarregar o arquivo para atualizar a definição da função. Por exemplo:

CREATE OR REPLACE FUNCTION funcao_teste(integer) RETURNS integer AS $$
          ....
$$ LANGUAGE plpgsql;

Na linha de comando do psql a definição da função pode ser carregada ou recarregada utilizando

\i nome_do_arquivo.sql

e logo em seguida podem ser executados os comandos SQL que testam a função.

Outra boa maneira de desenvolver em PL/pgSQL, é utilizar uma ferramenta de acesso ao banco de dados com interface gráfica que facilite o desenvolvimento em linguagem procedural. Um exemplo deste tipo de ferramenta é o PgAccess, mas existem outras. Estas ferramentas geralmente disponibilizam funcionalidades úteis como o escape de apóstrofos, e tornam mais fácil recriar e depurar funções.

35.2.1. Tratamento dos apóstrofos

O código da função PL/pgSQL é especificado no comando CREATE FUNCTION como um literal cadeia de caracteres. Se o literal cadeia de caracteres for escrito da maneira usual, que é entre apóstrofos ('), então os apóstrofos dentro do corpo da função devem ser duplicados; da mesma maneira, as contrabarras dentro do corpo da função (\) devem ser duplicadas. Duplicar os apóstrofos é no mínimo entediante, e nos casos mais complicados pode tornar o código difícil de ser compreendido, porque pode-se chegar facilmente a uma situação onde são necessários seis ou mais apóstrofos adjacentes. Por isso, recomenda-se que o corpo da função seja escrito em um literal cadeia de caracteres delimitado por "cifrão" (consulte a Seção 4.1.2.2) em vez de delimitado por apóstrofos. Na abordagem delimitada por cifrão os apóstrofos nunca são duplicados e, em vez disso, toma-se o cuidado de escolher uma marca diferente para cada nível de aninhamento necessário. Por exemplo, o comando CREATE FUNCTION pode ser escrito da seguinte maneira:

CREATE OR REPLACE FUNCTION funcao_teste(integer) RETURNS integer AS $PROC$
          ....
$PROC$ LANGUAGE plpgsql;

No corpo da função podem ser utilizados apóstrofos para delimitar cadeias de caracteres simples nos comandos SQL, e $$ para delimitar fragmentos de comandos SQL montados como cadeia de caracteres. Se for necessário delimitar um texto contendo $$, deve ser utilizado $Q$, e assim por diante.

O quadro abaixo mostra o que deve ser feito para escrever o corpo da função entre apóstrofos (sem uso da delimitação por cifrão). Pode ser útil para tornar códigos anteriores à delimitação por cifrão mais fácil de serem compreendidos.

1 apóstrofo

para começar e terminar o corpo da função como, por exemplo:

CREATE FUNCTION foo() RETURNS integer AS '
          ....
' LANGUAGE plpgsql;

Em todas as ocorrências dentro do corpo da função os apóstrofos devem aparecer em pares.

2 apóstrofos

Para literais cadeia de caracteres dentro do corpo da função como, por exemplo:

a_output := ''Blah'';
SELECT * FROM users WHERE f_nome=''foobar'';

Na abordagem delimitada por cifrão seria escrito apenas

a_output := 'Blah';
SELECT * FROM users WHERE f_nome='foobar';

que é exatamente o código visto pelo analisador do PL/pgSQL nos dois casos.

4 apóstrofos

Quando é necessário colocar um apóstrofo em uma constante cadeia de caracteres dentro do corpo da função como, por exemplo:

a_output := a_output || '' AND nome LIKE ''''foobar'''' AND xyz''

O verdadeiro valor anexado a a_output seria: AND nome LIKE 'foobar' AND xyz.

Na abordagem delimitada por cifrão seria escrito

a_output := a_output || $$ AND nome LIKE 'foobar' AND xyz$$

tendo-se o cuidado de que todos os delimitadores por cifrão envolvendo este comando não sejam apenas $$.

6 apóstrofos

Quando o apóstrofo na cadeia de caracteres dentro do corpo da função está adjacente ao final da constante cadeia de caracteres como, por exemplo:

a_output := a_output || '' AND nome LIKE ''''foobar''''''

O valor anexado à a_output seria: AND nome LIKE 'foobar'.

Na abordagem delimitada por cifrão se tornaria

a_output := a_output || $$ AND nome LIKE 'foobar'$$
10 apóstrofos

Quando é necessário colocar dois apóstrofos em uma constante cadeia de caracteres (que necessita de 8 apóstrofos), e estes dois apóstrofos estão adjacentes ao final da constante cadeia de caracteres (mais 2 apóstrofos). Normalmente isto só é necessário quando são escritas funções que geram outras funções como no Exemplo 35-8. Por exemplo:

a_output := a_output || '' if v_'' ||
    referrer_keys.kind || '' like ''''''''''
    || referrer_keys.key_string || ''''''''''
    then return ''''''  || referrer_keys.referrer_type
    || ''''''; end if;'';

O valor de a_output seria então:

if v_... like ''...'' then return ''...''; end if;

Na abordagem delimitada por cifrão se tornaria

a_output := a_output || $$ if v_$$ || referrer_keys.kind || $$ like '$$
    || referrer_keys.key_string || $$'
    then return '$$  || referrer_keys.referrer_type
    || $$'; end if;$$;

onde se assume que só é necessário colocar um único apóstrofo em a_output, porque este será delimitado novamente antes de ser utilizado.

Uma outra abordagem é fazer o escape dos apóstrofos no corpo da função utilizando a contrabarra em vez de duplicá-los. Desta forma é escrito \'\' no lugar de ''''. Alguns acham esta forma mais fácil, porém outros não concordam.

SourceForge.net Logo CSS válido!