O acesso ao banco de dados a partir de uma função Perl pode ser feito através das seguintes funções:
spi_exec_query(consulta [, limite])
A função spi_exec_query executa um comando
SQL e retorna todo o conjunto de linhas como
uma referência a uma matriz de referências de
hash.
Se o limite especificado for maior
que zero, então a função spi_exec_query
trará no máximo limite linhas, como se
a consulta tivesse incluído uma cláusula LIMIT.
Omitir o limite, ou especificá-lo como
zero, resulta em nenhum limite de linhas.
Só se deve usar este comando quando se souber que o
conjunto de resultados será relativamente pequeno.
A seguir está um exemplo de uma consulta (comando
SELECT) com o número máximo opcional de linhas:
$rv = spi_exec_query('SELECT * FROM minha_tabela', 5);
Este comando retorna até 5 linhas da tabela
minha_tabela.
Se minha_tabela tiver a coluna
minha_coluna, poderá ser obtido o valor da
linha $i do resultado usando:
$foo = $rv->{rows}[$i]->{minha_coluna};
O número total de linhas retornadas de uma consulta pelo comando
SELECT pode ser acessado usando:
$nrows = $rv->{processed}
A seguir está um exemplo usando um tipo de comando diferente:
$query = "INSERT INTO minha_tabela VALUES (1, 'teste')"; $rv = spi_exec_query($query);
O status do comando pode acessado (por exemplo,
SPI_OK_INSERT) usando:
$res = $rv->{status};
Para obter o número de linhas afetadas, é usado:
$nrows = $rv->{processed};
A seguir está um exemplo completo:
CREATE TABLE teste (
i int,
v varchar
);
INSERT INTO teste (i, v) VALUES (1, 'primeira linha');
INSERT INTO teste (i, v) VALUES (2, 'segunda linha');
INSERT INTO teste (i, v) VALUES (3, 'TERCEIRA linha');
INSERT INTO teste (i, v) VALUES (4, 'imortal');
CREATE OR REPLACE FUNCTION test_munge()
RETURNS SETOF teste AS
$$
my $rv = spi_exec_query('select i, v from teste;');
my $status = $rv->{status};
my $nrows = $rv->{processed};
foreach my $rn (0 .. $nrows - 1) {
my $row = $rv->{rows}[$rn];
# somar 200 ao valor de 'i'
$row->{i} += 200 if defined($row->{i});
# transformar letras maiúsculas em minúsculas, e vice-versa
$row->{v} =~ tr/A-Za-z/a-zA-Z/ if (defined($row->{v}));
return_next($row);
}
return undef;
$$ LANGUAGE plperl;
SELECT * FROM test_munge();
i | v -----+---------------- 201 | PRIMEIRA LINHA 202 | SEGUNDA LINHA 203 | terceira LINHA 204 | IMORTAL (4 linhas)
spi_query(comando)
spi_fetchrow(cursor)
spi_cursor_close(cursor)
As funções
spi_query e spi_fetchrow
trabalham juntas como um par, para conjuntos de linhas que podem
ser grandes, ou para casos em que se deseja retornar as linhas
conforme elas chegam.
A função spi_fetchrow trabalha
somente com spi_query.
O exemplo a seguir mostra como as duas são usadas juntas:
CREATE TYPE tipo_foo AS (numero INTEGER, texto TEXT);
CREATE OR REPLACE FUNCTION lotsa_md5 (INTEGER) RETURNS SETOF tipo_foo AS $$
use Digest::MD5 qw(md5_hex);
my $file = '/usr/share/dict/portuguese';
my $t = localtime;
elog(NOTICE, "abrindo arquivo $file em $t" );
open my $fh, '<', $file # eita, é um acesso a arquivo!
or elog(ERROR, "não foi possível abrir $file para leitura: $!");
my @words = <$fh>;
close $fh;
$t = localtime;
elog(NOTICE, "arquivo $file fechado em $t");
chomp(@words);
my $row;
my $sth = spi_query("SELECT * FROM generate_series(1,$_[0]) AS b(a)");
while (defined ($row = spi_fetchrow($sth))) {
return_next({
numero => $row->{a},
texto => md5_hex($words[rand @words])
});
}
return;
$$ LANGUAGE plperlu;
SELECT * from lotsa_md5(5);
NOTA: abrindo arquivo /usr/share/dict/portuguese em Tue May 19 16:11:58 2026
NOTA: arquivo /usr/share/dict/portuguese fechado em Tue May 19 16:11:58 2026
numero | texto
--------+----------------------------------
1 | 94eae375e57bed50a91f1b31c665922d
2 | b67c8dd88d65c6c9fd1ba85f012e32cb
3 | d81f09cece6834e2e7fdf33dd634631f
4 | d33e8bd813ff8c67d7c135d30e64988a
5 | f4fdb4bd7be4b154056617bb2c7502ca
(5 linhas)
Normalmente, a função spi_fetchrow deve ser
chamada até que retorne undef, indicando
não haver mais linhas para ler.
O cursor retornado por spi_query é
automaticamente liberado quando spi_fetchrow
retorna undef.
Se não for desejado ler todas as linhas, deve ser chamada a função
spi_cursor_close para liberar o cursor.
Não fazer isto resulta em vazamento de memória.
spi_prepare(comando, tipos_de_dados_dos_argumentos)
spi_query_prepared(plano, argumentos)
spi_exec_prepared(plano [, atributos], argumentos)
spi_freeplan(plano)
As funções spi_prepare,
spi_query_prepared,
spi_exec_prepared e
spi_freeplan implementam as mesmas
funcionalidades, mas para consultas preparadas.
A função spi_prepare aceita uma cadeia de
caracteres de consulta com espaços reservados para argumentos
numerados ($1, $2, etc.), e uma lista de cadeia de caracteres de
tipos de dados dos argumentos:
$plan = spi_prepare('
SELECT *
FROM teste
WHERE id > $1 AND nome = $2', 'INTEGER', 'TEXT');
Uma vez que o plano de consulta esteja preparado por uma chamada
à função spi_prepare, o plano pode ser usado
em vez da cadeia de caracteres da consulta, seja em
spi_exec_prepared, onde o resultado é o mesmo
que o retornado por spi_exec_query, ou em
spi_query_prepared que retorna um cursor
exatamente como spi_query faz, que depois pode
ser passado para spi_fetchrow.
O segundo parâmetro opcional para spi_exec_prepared
é uma referência hash de atributos;
o único atributo com suporte atualmente é limit,
que define o número máximo de linhas retornadas pela consulta.
Omitir limite ou especificá-lo como zero resulta
em nenhum limite de linhas.
A vantagem das consultas preparadas é ser possível usar um plano
preparado para mais de uma execução da consulta.
Após não ser mais necessário, o plano poderá ser liberado usando
spi_freeplan:
CREATE OR REPLACE FUNCTION iniciar()
RETURNS VOID AS
$$
$_SHARED{plano} = spi_prepare(
'SELECT (now() + $1)::date AS now', 'INTERVAL');
$$ LANGUAGE plperl;
CREATE OR REPLACE FUNCTION adicionar_tempo( INTERVAL )
RETURNS TEXT AS
$$
return spi_exec_prepared(
$_SHARED{plano},
$_[0]
)->{rows}->[0]->{now};
$$ LANGUAGE plperl;
CREATE OR REPLACE FUNCTION terminar()
RETURNS VOID AS
$$
spi_freeplan( $_SHARED{plano});
undef $_SHARED{plano};
$$ LANGUAGE plperl;
SELECT iniciar();
SELECT adicionar_tempo('1 day'),
adicionar_tempo('2 days'),
adicionar_tempo('3 days');
SELECT terminar();
adicionar_tempo | adicionar_tempo | adicionar_tempo -----------------+-----------------+----------------- 2026-05-20 | 2026-05-21 | 2026-05-22 (1 linha)
Note que o índice do parâmetro em spi_prepare
é definido via $1, $2,
$3, etc., então deve-se evitar declarar cadeias
de caracteres de consulta delimitadas que podem facilmente levar
a erros difíceis de detectar.
Este outro exemplo mostra o uso de um parâmetro opcional em
spi_exec_prepared:
CREATE TABLE hospedeiros AS
SELECT id, ('192.168.1.'||id)::inet AS endereco
FROM generate_series(1,3) AS id;
CREATE OR REPLACE FUNCTION iniciar_consulta_hospedeiros()
RETURNS VOID AS
$$
$_SHARED{plan} = spi_prepare('SELECT * FROM hospedeiros
WHERE endereco << $1', 'inet');
$$ LANGUAGE plperl;
CREATE OR REPLACE FUNCTION consulta_hospedeiros(inet)
RETURNS SETOF hospedeiros AS
$$
return spi_exec_prepared(
$_SHARED{plan},
{limit => 2},
$_[0]
)->{rows};
$$ LANGUAGE plperl;
CREATE OR REPLACE FUNCTION liberar_consulta_hospedeiros()
RETURNS VOID AS
$$
spi_freeplan($_SHARED{plan});
undef $_SHARED{plan};
$$ LANGUAGE plperl;
SELECT iniciar_consulta_hospedeiros();
SELECT consulta_hospedeiros('192.168.1.0/30');
SELECT liberar_consulta_hospedeiros();
consulta_hospedeiros ---------------------- (1,192.168.1.1) (2,192.168.1.2) (2 linhas)
spi_commit()
spi_rollback()
Efetiva (commit), ou desfaz
(roll back), a transação corrente.
Só podem ser chamados em um procedimento, ou bloco de código
anônimo (comando DO), chamado do nível superior.
(Note que não é possível executar os comandos
COMMIT ou ROLLBACK do
SQL via spi_exec_query,
ou similar. Tem que ser feito usando estas funções.)
Após a transação ser encerrada, uma nova transação é iniciada
automaticamente, portanto, não há uma função separada para isto.
A seguir está um exemplo:
CREATE OR REPLACE PROCEDURE testa_transacao()
LANGUAGE plperl AS
$$
foreach my $i (0..9) {
spi_exec_query("INSERT INTO teste (i) VALUES ($i)");
if ($i % 2 == 0) {
spi_commit();
} else {
spi_rollback();
}
}
$$;
CALL testa_transacao();
elog(nível, mensagem)
Lança um registro ou mensagem de erro. Os níveis possíveis são
DEBUG, LOG,
INFO, NOTICE,
WARNING, e ERROR.
ERROR levanta uma condição de erro; se não
for interceptado pelo código Perl
envoltório, o erro se propagará para a consulta da chamada, fazendo
com que a transação ou subtransação corrente seja interrompida.
É de fato o mesmo que o comando die do
Perl.
Os outros níveis geram apenas mensagens de diferentes níveis
de prioridade.
Se as mensagens de uma determinada prioridade serão mostradas ao
cliente, escritas no arquivo de registro de eventos do servidor
(log), ou as duas coisas,
são controlados pelas variáveis de configuração
log_min_messages e
client_min_messages.
Veja Configuração do servidor para obter mais informações.
quote_literal(cadeia_de_caracteres)
Retorna a cadeia de caracteres fornecida adequadamente
delimitada para ser usada como um literal cadeia de caracteres,
em uma cadeia de caracteres de instrução do
SQL.
Apóstrofos e contrabarras incorporados são devidamente duplicados.
Note que quote_literal retorna
undef para uma entrada undef;
se o argumento puder ser undef, a função
quote_nullable é geralmente mais adequada.
quote_nullable(cadeia_de_caracteres)
Retorna a cadeia de caracteres fornecida adequadamente
delimitada para ser usada como um literal cadeia de caracteres,
em uma cadeia de caracteres de instrução do
SQL; ou, se o argumento for
undef, retorna a cadeia de caracteres "NULL"
sem delimitador.
Apóstrofos e contrabarras presentes são devidamente duplicados.
quote_ident(cadeia_de_caracteres)
Retorna a cadeia de caracteres fornecida adequadamente delimitada para ser usada como um identificador, em uma cadeia de caracteres de instrução do SQL. Os delimitadores são adicionadas apenas se necessário (ou seja, se a cadeia de caracteres contiver caracteres não identificadores, ou contiver letras maiúsculas e minúsculas). As aspas incorporadas são devidamente duplicadas.
decode_bytea(cadeia_de_caracteres)
Retorna os dados binários sem escape representados pelo conteúdo
da cadeia de caracteres fornecida, que deve estar codificada em
bytea.
encode_bytea(cadeia_de_caracteres)
Retorna a forma codificada em bytea do conteúdo
dos dados binários da cadeia de caracteres fornecida.
encode_array_literal(matriz)
encode_array_literal(matriz, delimitador)
Retorna o conteúdo da matriz referenciada como uma cadeia de
caracteres em formato literal de matriz
(veja Entrada dos valores da matriz).
Retorna o valor do argumento inalterado, se não for uma
referência a uma matriz.
O delimitador usado entre os elementos do literal matriz
assume como padrão a ", ", se o delimitador
não for especificado, ou for undef.
encode_typed_literal(valor, nome_do_tipo_de_dados)
Converte uma variável do Perl no valor do tipo de dados passado como segundo argumento, e retorna uma representação de cadeia de caracteres desse valor. Trata corretamente as matrizes aninhadas e valores de tipos de dados compostos.
encode_array_constructor(matriz)
Retorna o conteúdo da matriz referenciada como uma cadeia de
caracteres no formato do construtor de matriz
(veja Construtores de matriz).
Os valores delimitados são delimitados usando
quote_nullable.
Retorna o valor do argumento, delimitado usando
quote_nullable, se não for uma referência
a uma matriz.
looks_like_number(cadeia_de_caracteres)
Retorna verdade, se o conteúdo da cadeia de caracteres
fornecida parecer um número, segundo o
Perl, ou retorna falso caso contrário.
Retorna undef se o argumento for
undef.
Espaços à esquerda e à direita são ignorados.
Inf e Infinity
são considerados números.
is_array_ref(argumento)
Retorna verdade se o argumento fornecido puder ser
tratado como uma referência de matriz, ou seja, se a referência
do argumento for ARRAY ou
PostgreSQL::InServer::ARRAY.
Caso contrário, retorna falso.