Documentação do PostgreSQL 8.0.0 | ||||
---|---|---|---|---|
Anterior | Início | Capítulo 35. PL/pgSQL - Linguagem procedural SQL | Fim | Próxima |
Todas as variáveis utilizadas em um bloco devem ser declaradas na seção de declarações do bloco (A única exceção é a variável de laço do FOR interagindo sobre um intervalo de valores inteiros, que é automaticamente declarada como sendo do tipo inteiro).
As variáveis da linguagem PL/pgSQL podem possuir qualquer tipo de dado da linguagem SQL, como integer, varchar e char.
Abaixo seguem alguns exemplos de declaração de variáveis:
id_usuario integer; quantidade numeric(5); url varchar; minha_linha nome_da_tabela%ROWTYPE; meu_campo nome_da_tabela.nome_da_coluna%TYPE; uma_linha RECORD;
A sintaxe geral para declaração de variáveis é:
nome [ CONSTANT ] tipo [ NOT NULL ] [ { DEFAULT | := } expressão ];
A cláusula DEFAULT, se for fornecida, especifica o valor inicial atribuído à variável quando o processamento entra no bloco. Se a cláusula DEFAULT não for fornecida, então a variável é inicializada com o valor nulo do SQL. A opção CONSTANT impede que seja atribuído valor a variável e, portanto, seu valor permanece constante pela duração do bloco. Se for especificado NOT NULL, uma atribuição de valor nulo resulta em um erro em tempo de execução. Todas as variáveis declaradas como NOT NULL devem ter um valor padrão não nulo especificado.
O valor padrão é avaliado toda vez que a execução entra no bloco. Portanto, por exemplo, atribuir now() a uma variável do tipo timestamp faz com que a variável possua a data e hora da chamada corrente à função, e não de quando a função foi pré-compilada.
Exemplos:
quantidade integer DEFAULT 32; url varchar := ''http://meu-site.com''; id_usuario CONSTANT integer := 10;
Os parâmetros passados para as funções recebem como nome os identificadores $1, $2, etc. Opcionalmente, para melhorar a legibilidade do código, podem ser declarados aliases para os nomes dos parâmetros $n. Para fazer referência ao valor do parâmetro, pode ser utilizado tanto o aliás quanto o identificador numérico.
Existem duas maneiras de criar um aliás. A forma preferida é fornecer nome ao parâmetro no comando CREATE FUNCTION como, por exemplo:
CREATE FUNCTION taxa_de_venda(subtotal real) RETURNS real AS $$ BEGIN RETURN subtotal * 0.06; END; $$ LANGUAGE plpgsql;
A outra maneira, que era a única disponível antes da versão 8.0 do PostgreSQL, é declarar explicitamente um aliás utilizando a sintaxe de declaração
nome ALIAS FOR $n;
O exemplo acima escrito utilizando este estilo fica da seguinte maneira:
CREATE FUNCTION taxa_de_venda(real) RETURNS real AS $$ DECLARE subtotal ALIAS FOR $1; BEGIN RETURN subtotal * 0.06; END; $$ LANGUAGE plpgsql;
Alguns outros exemplos:
CREATE FUNCTION instr(varchar, integer) RETURNS integer AS $$ DECLARE v_string ALIAS FOR $1; index ALIAS FOR $2; BEGIN -- algum processamento neste ponto END; $$ LANGUAGE plpgsql; CREATE FUNCTION concatenar_campos_selecionados(in_t nome_da_tabela) RETURNS text AS $$ BEGIN RETURN in_t.f1 || in_t.f3 || in_t.f5 || in_t.f7; END; $$ LANGUAGE plpgsql;
Quando o tipo retornado por uma função PL/pgSQL é declarado como sendo de um tipo polimórfico (anyelement ou anyarray), é criado o parâmetro especial $0. Seu tipo de dado é o tipo de dado real a ser retornado pela função, conforme deduzido a partir dos tipos da entrada corrente (consulte a Seção 31.2.5). Isto permite à função descobrir o verdadeiro tipo de dado retornado para a entrada corrente conforme mostrado na Seção 35.4.2. O parâmetro $0 é inicializado como nulo e pode ser modificado pela função, portanto pode ser utilizado para armazenar o valor a ser retornado se for desejado, embora não seja requerido. Também pode ser criado um aliás para o parâmetro $0. Por exemplo, esta função funciona com qualquer tipo de dado que possua o operador +:
CREATE FUNCTION somar_tres_valores(v1 anyelement, v2 anyelement, v3 anyelement) RETURNS anyelement AS $$ DECLARE resultado ALIAS FOR $0; BEGIN resultado := v1 + v2 + v3; RETURN resultado; END; $$ LANGUAGE plpgsql; SELECT somar_tres_valores(10,20,30); somar_tres_valores -------------------- 60 (1 linha) SELECT somar_tres_valores(1.1,2.2,3.3); somar_tres_valores -------------------- 6.6 (1 linha)
variável%TYPE
A expressão %TYPE fornece o tipo de dado da variável ou da coluna da tabela. Pode ser utilizada para declarar variáveis que armazenam valores do banco de dados. Por exemplo, supondo que exista uma coluna chamada id_usuario na tabela usuarios, para declarar uma variável com o mesmo tipo de dado de usuarios.id_usuario deve ser escrito:
id_usuario usuarios.id_usuario%TYPE;
Utilizando %TYPE não é necessário conhecer o tipo de dado da estrutura sendo referenciada e, ainda mais importante, se o tipo de dado do item referenciado mudar no futuro (por exemplo: o tipo de dado de id_usuario for mudado de integer para real), não será necessário mudar a definição na função.
A expressão %TYPE é particularmente útil em funções polimórficas, uma vez que os tipos de dado das variáveis internas podem mudar de uma chamada para outra. Podem ser criadas variáveis apropriadas aplicando %TYPE aos argumentos ou guardadores de lugar do resultado da função.
nome nome_da_tabela%ROWTYPE; nome nome_do_tipo_composto;
Uma variável de tipo composto é chamada de variável linha (ou variável tipo-linha). Este tipo de variável pode armazenar toda uma linha de resultado de um comando SELECT ou FOR, desde que o conjunto de colunas do comando corresponda ao tipo declarado para a variável. Os campos individuais do valor linha são acessados utilizando a notação usual de ponto como, por exemplo, variável_linha.campo.
Uma variável-linha pode ser declarada como tendo o mesmo tipo de dado das linhas de uma tabela ou de uma visão existente, utilizando a notação nome_da_tabela%ROWTYPE; ou pode ser declarada especificando o nome de um tipo composto (Uma vez que todas as tabelas possuem um tipo composto associado, que possui o mesmo nome da tabela, na verdade não faz diferença para o PostgreSQL se %ROWTYPE é escrito ou não, mas a forma contendo %ROWTYPE é mais portável).
Os parâmetros das funções podem ser de tipo composto (linhas completas da tabela). Neste caso, o identificador correspondente $n será uma variável linha, e os campos poderão ser selecionados a partir deste identificador como, por exemplo, $1.id_usuario.
Somente podem ser acessadas na variável tipo-linha as colunas definidas pelo usuário presentes na linha da tabela, a coluna OID e as outras colunas do sistema não podem ser acessadas por esta variável (porque a linha pode ser de uma visão). Os campos do tipo-linha herdam o tamanho do campo da tabela, ou a precisão no caso de tipos de dado como char(n).
Abaixo está mostrado um exemplo de utilização de tipo composto:
CREATE FUNCTION mesclar_campos(t_linha nome_da_tabela) RETURNS text AS $$ DECLARE t2_linha nome_tabela2%ROWTYPE; BEGIN SELECT * INTO t2_linha FROM nome_tabela2 WHERE ... ; RETURN t_linha.f1 || t2_linha.f3 || t_linha.f5 || t2_linha.f7; END; $$ LANGUAGE plpgsql; SELECT mesclar_campos(t.*) FROM nome_da_tabela t WHERE ... ;
nome RECORD;
As variáveis registro são semelhantes às variáveis tipo-linha, mas não possuem uma estrutura pré-definida. Assumem a estrutura da linha para a qual são atribuídas pelo comando SELECT ou FOR. A subestrutura da variável registro pode mudar toda vez que é usada em uma atribuição. Como conseqüência, antes de ser utilizada em uma atribuição a variável registro não possui subestrutura, e qualquer tentativa de acessar um de seus campos produz um erro em tempo de execução.
Deve ser observado que RECORD não é um tipo de dado real, mas somente um guardador de lugar. Deve-se ter em mente, também, que declarar uma função do PL/pgSQL como retornando o tipo record não é exatamente o mesmo conceito de variável registro, embora a função possa utilizar uma variável registro para armazenar seu resultado. Nos dois casos a verdadeira estrutura da linha é desconhecida quando a função é escrita, mas na função que retorna o tipo record a estrutura verdadeira é determinada quando o comando que faz a chamada é analisado, enquanto uma variável registro pode mudar a sua estrutura de linha em tempo de execução.
RENAME nome_antigo TO novo_nome;
O nome de uma variável, registro ou linha pode ser mudado através da instrução RENAME. A utilidade principal é quando NEW ou OLD devem ser referenciados por outro nome dentro da função de gatilho. Consulte também ALIAS.
Exemplos:
RENAME id TO id_usuario; RENAME esta_variável TO aquela_variável;
Nota: RENAME parece estar com problemas desde o PostgreSQL 7.3. A correção possui baixa prioridade, porque o ALIAS cobre a maior parte dos usos práticos do RENAME.