Escolar Documentos
Profissional Documentos
Cultura Documentos
FuncoesPG PDF
FuncoesPG PDF
O SGBD PostgreSQL permite que sejam criadas funes pr-definidas pelo usurio sendo que as
mesmas so armazenadas como objetos do SGBD e podem ser executadas diretamente no BD sem a
necessidade da criao de uma aplicao externa. As funes criadas e armazenadas no banco so
chamadas, historicamente, de stored procedures (procedimentos armazenados). Esse termo
herana do SGBD Oracle. Em PostgreSQL, como na linguagem C, no existem procedimentos,
tudo funo. Um procedimento um tipo especial de funo que retorna vazio (void).
A estrutura do PL/pgSQL
PL/pgSQL um linguagem estruturada por blocos. A definio de uma funo tem que ser um
bloco.
Um bloco definido como:
[ <<rotulo>> ]
[ DECLARE
declaraes ]
BEGIN
comandos
END [ rotulo ];
Cada declarao e cada comando dentro de um bloco termina com um ponto e vrgula. Um bloco
que aparece dentro de outro deve ter um ponto e vrgula aps o END, como apresentado acima.
Contudo, o ltimo END (o END mais externo) no necessita de ponto e vrgula.
Um rtulo necessrio apenas se queira-se identificar o bloco para uso do comando EXIT, ou
qualificar os nomes de variveis declaradas no bloco. Se um rtulo dado aps o comando END,
esse rtulo deve coincidir com o rtulo dado no incio do bloco.
Existem duas formas de comentar em PL/pgSQL. Um hfen duplo (--) inicia um comentrio que
ocupa apenas uma linha. Um /* inicia um bloco de comentrio que vai at a ocorrncia de */.
Qualquer comando na seo de comandos de um bloco pode ser um subbloco. Sublocos podem ser
utilizados para agrupamentos lgicos ou para localizar variveis dentro de um pequeno grupo de
comandos. Variveis declaradas em um subbloco so locais ao subbloco. Caso um varivel local a
um subbloco tenha o mesmo nome de uma varivel mais externa, essa pode ser acessada
qualificando a varivel com o nome do bloco externo.
Exemplo:
Nota: existe um bloco mais externo que leva o nome da funo criada.
Uma funo pode ser testada chamando-a atravs do comando SELECT vazio.
Select funcaoqquer();
Declaraes
Todas as variveis utilizadas em um bloco devem ser declaradas na seo especificada para tal
(DECLARE) a nica exceo so as variveis de lao de um FOR de inteiros que automtica
declarada com uma varivel do tipo inteiro, bem como laos cursores onde as variveis so
declaradas automaticamente como registros.
As variveis PL/pgSQL podem ser de qualquer tipo dos dados SQL, tais como integer, varchar, e
char.
Algumas declaraes vlidas:
user_id integer;
qtdade numeric(5);
url varchar;
minhatupla tablename%ROWTYPE;
meucamapo tablename.columnname%TYPE;
seta RECORD;
A clusula DEFAULT, se utilizada, especifica o valor inicial associado varivel quando o bloco
acessado. Se DEFAULT no especificado ento a varivel inicializada com NULL. A opo
CONSTANT protege a varivel (que torna-se uma constante) de ser alterada durante sua existncia
no blobo. Se NOT NULL especificado, se a varivel for associada ao valor NULL, ocorre um
erro em tempo de execuo. Todas as variveis declaradas como NOT NULL devem ter um valor
no nulo como DEFAULT.
O valor default dado a uma varivel associado a mesma toda as vezes que bloco for executado
(no apenas na primeira vez).
Exemplos:
Existem duas maneiras para se criar um apelido. O jeito preferido dar um nome ao parmetro no
momento de criar a funo, por exemplo:
A outra maneira, que era a nica nas verses anteriores a 8.0, explicitar a declarao de um
apelido atravs da sintaxe:
apelido ALIAS FOR $n;
Esses dois exemplos no so estritamente equivalentes. No primeiro caso, subtotal poderia ser
referenciado como taxa_venda.subtotal, j no segundo caso, no poderia pois o rtulo default
(conforme apresentado acima) pode ser utilizado por variveis especiais e pelos parmetros.
Outro exemplo:
Quando um parmetro for declarado como de sada (utilizando OUT) funciona como uma varivel
que inicializada com NULL e deve ser associada a um valor durante a execuo de uma funo.
Esse tipo de parmetro retorna automaticamente um valor para o chamador.
CREATE FUNCTION soma_mult(x int, y int, OUT soma int, OUT mult int) AS $$
BEGIN
soma := x + y;
mult := x * y;
END;
$$ LANGUAGE plpgsql;
Existem uma srie de tipos que podem ser retornados, por exemplo, RETURNS TABLE retorna
uma tabela (resultado de uma consulta):
Este tipo de retorno equivalente ao uso de parmetros do tipo OUT ou especificar RETURNS
SETOF algum tipo.
Quando o tipo de retorno de uma funo PL/pgSQL declarado como polimrfico (anyelement,
anyarray, anynonarray, ou anyenum), um parmetro especial $0 criado. O tipo de dado do mesmo
o retornado pela funo, deduzido a partir dos tipos de entrada.
O mesmo efeito pode ser conseguido declarando um ou mais parmetros do tipo OUT como
polimrficos. Neste caso, o parmetro especial $0 no precisa ser utilizado; os prprios parmetros
OUT servem para o propsito:
user_id users.user_id%TYPE;
Utilizando %TYPE no necessrio conhecer o tipo de dado que se est referenciando e, mais
importante, se o tipo de dado do item referenciado muda, a varivel que referencia o tipo muda
tambm sem a necessidade de alterar a funo.
%TYPE is particularly valuable in polymorphic functions, since the data types needed for internal
variables can change from one call to the next. Appropriate variables can be created by applying
%TYPE to the function's arguments or result placeholders.
Tipos Linhas
nome nome_tabeka%ROWTYPE;
Este tipo de varivel chamado de varivel de linha. Tal varivel pode armazenar toda a linha de
um SELECT. Para acessar os atributos, utilize a notao de ponto. Por exemplo, variavel.atributo.
Parmetros em funes podem ser do tipo linha tambm. Neste caso, a posio correspondente do
parmetro $n pode ser utilizado com um varivel de linha, por exemplo, $1.user_id.
Apenas as colunas definidas pelo usurio em um tabela podem ser acessadas com este tipo de
varivel. Pseudo-colunas (como por exemplo OID) no so acessveis.
O exemplo abaixo utiliza esta definio. Imagine que as tabelas usuario e log existam e que os
atributos citados existam.
Utilizao:
SELECT merge_fields(t.*) FROM usuario t WHERE <condicao>;
Funes SQL
Funes SQL executam uma lista arbitrria de comandos SQL, retornando o resultado da ltima
consulta na lista. No caso simples (no utilizando conjunto), a primeira linha da ltima consulta ser
o valor de retorno (essa linha no pode ser definida, exceto se utilizarmos o ORDER BY). Se a
ltima consulta no retornar linha alguma, um valor null ser retornado.
Tambm podemos declarar o retorno de uma funo SQL como conjunto, colocando no retorno
SETOF <algumTipo> ou RETURNS TABLE(colunas). Neste caso, todas as linhas da ltima
consulta so retornadas.
O corpo de uma funo SQL uma lista de comandos SQL separada por ponto e vrugla. O ponto e
vrgula aps o ltimo comando opcional. Exceto se a funo tenha sido declarada com VOID, o
ltimo comando tem que ser um SELECT, ou um INSERT, UPDATE, ou DELETE que tenha uma
clusula RETURNING.
Exemplos:
SELECT clean_emp();
clean_emp
-----------
(1 row)
Pode-se colocar o comando abaixo para atualizar uma tabela (minhatabela) com um valor de
parmetro (o primeiro):
INSERT INTO mytable VALUES ($1);
Mas o parmetro no pode ser utilizado para substituir nome de atributo/coluna. Assim, o comando
abaixo no funcionaria:
INSERT INTO $1 VALUES (42);
SELECT um();
um
-----
1
answer
--------
3
CREATE FUNCTION tf1 (integer, numeric) RETURNS integer AS $$
UPDATE bank
SET balance = balance - $2
WHERE accountno = $1;
SELECT 1;
$$ LANGUAGE SQL;
Utilizao:
A funo melhorada:
Utilizando RETURNING:
Tipos Compostos
Utilizando tipos tabela e outros em funes SQL.
name | dream
------+-------
Bill | 8400
Perceba que a sintaxe $1.salary seleciona um campo do parmetro linha passado. Tambm perceba
que o comando SELECT utiliza * para selecionar todos os campos da linha corrente da tabela que
faz parte do parmetro. Podemos referenciar a tabela da seguinte forma:
SELECT getname(new_emp());
getname
---------
None
(1 row)
SELECT add_em(3,7);
add_em
--------
10
(1 row)
CREATE FUNCTION sum_n_product (x int, y int, OUT sum int, OUT product int)
AS 'SELECT $1 + $2, $1 * $2'
LANGUAGE SQL;
Parmetros da sada no so considerados como parte da assinatura da funo, assim, para excluir a
funo sum_n_product do banco podemos executar:
DROP FUNCTION sum_n_product (x int, y int, OUT sum int, OUT product int);
ou
DROP FUNCTION sum_n_product (int, int);
Funes como Tabelas
CREATE TABLE foo (fooid int, foosubid int, fooname text);
INSERT INTO foo VALUES (1, 1, 'Joe');
INSERT INTO foo VALUES (1, 2, 'Ed');
INSERT INTO foo VALUES (2, 1, 'Mary');
Retornando Conjuntos
CREATE FUNCTION getfoo(int) RETURNS SETOF foo AS $$
SELECT * FROM foo WHERE fooid = $1;
$$ LANGUAGE SQL;
Essa classificao de funes permitem otimizar a chamada das mesmas. Dependendo do objetivo
da funo, pode-se colocar o tipo mais restrito, IMMUTABLE. Neste caso, a execuo da funo
poder ser otimizada de forma melhor.
Porm, a maioria das funes se enquadram como VOLATILE, pois a maioria das funes SQL
precisam retornar valores diferentes a cada chamada.