Documentação do PostgreSQL 8.0.0 | ||||
---|---|---|---|---|
Anterior | Início | Capítulo 35. PL/pgSQL - Linguagem procedural SQL | Fim | Próxima |
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.
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.
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.
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.
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 $$.
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'$$
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.