DECLARE

DECLARE — define um cursor

Sinopse

DECLARE nome [ BINARY ] [ ASENSITIVE | INSENSITIVE ] [ [ NO ] SCROLL ]
    CURSOR [ { WITH | WITHOUT } HOLD ] FOR consulta

Descrição

O comando DECLARE permite que o usuário crie cursores, que podem ser usados para recuperar um pequeno número de linhas por vez de uma consulta maior. Após o cursor ser criado, as linhas são buscadas usando o comando FETCH.

Nota

Esta página descreve o uso de cursores no nível de comando SQL. Caso se esteja tentando usar cursores numa função escrita em PL/pgSQL, as regras são diferentes — veja Seção 41.7.

Parâmetros

nome

O nome do cursor a ser criado. Este nome deve ser diferente de qualquer outro nome de cursor ativo na sessão.

BINARY

Faz com que o cursor retorne os dados no formato binário, em vez de no formato texto.

ASENSITIVE
INSENSITIVE

A sensibilidade do cursor determina se as alterações nos dados subjacentes ao cursor, feitas na mesma transação, após o cursor ser declarado, são visíveis ao cursor. INSENSITIVE significa que não são visíveis, ASENSITIVE significa que o comportamento depende da implementação. Um terceiro comportamento, SENSITIVE, que significa que estas mudanças são visíveis ao cursor, não está disponível no PostgreSQL. No PostgreSQL, todos os cursores são insensíveis; portanto, estas palavras-chave não têm efeito, sendo aceitas apenas para manter a compatibilidade com o padrão SQL.

Especificar INSENSITIVE junto com FOR UPDATE ou FOR SHARE, é um erro.

SCROLL
NO SCROLL

SCROLL (rolagem) especifica que o cursor pode ser usado para recuperar linhas de maneira não sequencial (por exemplo, para trás). Dependendo da complexidade do plano de execução da consulta, especificar SCROLL pode impor uma penalidade de desempenho no tempo de execução da consulta. NO SCROLL especifica que o cursor não pode ser usado para recuperar linhas de maneira não sequencial. O padrão é permitir a rolagem em alguns casos; não é o mesmo que especificar SCROLL. Veja Notas para obter detalhes.

WITH HOLD
WITHOUT HOLD

WITH HOLD especifica que o cursor pode continuar sendo usado após a transação que o criou ser efetivada (commited) com sucesso. WITHOUT HOLD especifica que o cursor não pode ser usado fora da transação que o criou. Se não for especificado nem WITHOUT HOLD ou WITH HOLD, o padrão será WITHOUT HOLD.

consulta

Um comando SELECT ou VALUES que fornece as linhas a serem retornadas pelo cursor.

As palavras-chave ASENSITIVE, BINARY, INSENSITIVE, e SCROLL podem aparecer em qualquer ordem.

Notas

Os cursores normais retornam dados no formato texto, o mesmo que o comando SELECT produz. A opção BINARY especifica que o cursor deve retornar os dados no formato binário. Isto reduz o esforço de conversão, tanto para o servidor quanto para o cliente, ao custo de mais esforço do programador para lidar com formatos de dados binários dependentes de plataforma. Por exemplo, se uma consulta retornar o valor um de uma coluna inteira, será obtida uma cadeia de caracteres contendo 1 com o cursor padrão, enquanto com um cursor binário será obtido um campo de 4 bytes contendo a representação interna do valor (na ordem de bytes big-endian).

Os cursores binários devem ser usados com cuidado. Muitas aplicações, incluindo o psql, não estão preparadas para lidar com cursores binários, esperando que os dados retornem no formato texto.

Nota

Quando a aplicação cliente usa o protocolo de consulta estendida (extended query) para enviar o comando FETCH, a mensagem Bind do protocolo especifica se os dados devem ser retornados no formato texto ou binário. Esta escolha se sobrepõe ao modo como o cursor foi definido. O conceito de cursor binário como tal é, portanto, obsoleto ao usar o protocolo de consulta estendida — qualquer cursor pode ser tratado como texto ou binário.

A menos que seja especificado WITH HOLD, o cursor criado por este comando só poderá ser usado dentro da transação corrente. Assim, DECLARE sem WITH HOLD é inútil fora de um bloco de transação: o cursor sobreviveria apenas até o término da instrução. Portanto, o PostgreSQL irá relatar um erro se este comando for usado fora de um bloco de transação. Deve ser usado BEGIN e COMMIT (ou ROLLBACK) para definir um bloco de transação.

Se for especificado WITH HOLD, e a transação que criou o cursor for efetivada com sucesso, o cursor poderá continuar sendo acessado por transações subsequentes na mesma sessão. (Mas se a transação que criou o cursor for interrompida, o cursor será removido.) Um cursor criado com WITH HOLD é fechado por uma instrução CLOSE explícita para ele, ou quando a sessão termina. Na implementação corrente, as linhas representadas por um cursor persistente (WITH HOLD) são copiadas para um arquivo temporário, ou área de memória, para permanecerem disponíveis para as transações subsequentes.

WITH HOLD não pode ser especificado quando a consulta inclui FOR UPDATE ou FOR SHARE.

A opção SCROLL deve ser especificada ao definir um cursor que será usado para buscar para trás. Isto é requerido pelo padrão SQL. Entretanto, para manter a compatibilidade com versões anteriores, o PostgreSQL permitirá buscas para trás sem SCROLL, se o plano de consulta do cursor for simples o suficiente para que nenhuma sobrecarga extra seja necessária para suportá-lo. Porém, os desenvolvedores de aplicações são aconselhados a não confiar no uso de buscas para trás em um cursor que não tenha sido criado com SCROLL. Se for especificado NO SCROLL, as buscas para trás não serão permitidas em nenhum caso.

Buscas para trás também não são permitidas quando a consulta inclui FOR UPDATE ou FOR SHARE; portanto SCROLL não pode ser especificado nesses casos.

Cuidado

Os cursores roláveis podem fornecer resultados inesperados se chamarem funções voláteis (veja Categorias de volatilidade da função). Quando uma linha buscada anteriormente, é buscada novamente, as funções podem ser executadas novamente, talvez levando a resultados diferentes dos da primeira vez. É melhor especificar NO SCROLL para consultas envolvendo funções voláteis. Se isto não for prático, uma solução alternativa é declarar o cursor como SCROLL WITH HOLD, e efetivar a transação antes de ler qualquer linha dele. Isto irá fazer com que toda a saída do cursor seja materializada no armazenamento temporário, para que as funções voláteis sejam executadas exatamente uma vez para cada linha.

Se a consulta do cursor incluir FOR UPDATE ou FOR SHARE, as linhas retornadas serão bloqueadas no momento em que forem buscadas pela primeira vez, da mesma forma que para um comando SELECT regular com estas opções. Além disso, as linhas retornadas serão as versões mais atualizadas.

Cuidado

Geralmente é recomendado o uso de FOR UPDATE se o cursor se destina a ser usado com UPDATE ... WHERE CURRENT OF. ou DELETE ... WHERE CURRENT OF. Usar FOR UPDATE evita que outras sessões alterem as linhas entre a hora em que são buscadas e a hora em que são atualizadas. Sem FOR UPDATE, um comando WHERE CURRENT OF subsequente não terá efeito, se a linha tiver sido alterada depois que o cursor foi criado.

Outra razão para usar FOR UPDATE é que sem ele, um WHERE CURRENT OF subsequente poderá falhar se a consulta do cursor não atender às regras do padrão SQL para ser atualizável de forma simples (simply updatable) (em particular, o cursor deve referenciar apenas uma tabela, todas as colunas do resultado serem atualizáveis, e não usar agrupamento ou ORDER BY). Os cursores que não são atualizáveis de forma simples podem funcionar ou não, dependendo dos detalhes da escolha do plano; portanto, na pior das hipóteses, uma aplicação pode funcionar no teste e falhar em produção. Se for especificado FOR UPDATE, há garantia de que o cursor será atualizável.

O principal motivo para não usar FOR UPDATE com WHERE CURRENT OF é quando se necessita que o cursor seja rolável, ou isolado de atualizações simultâneas (ou seja, continue a mostrar os dados antigos). Se isto for um requisito, deve-se prestar muita atenção às advertências mostradas acima.

O padrão SQL faz apenas provisões para cursores em SQL incorporado. O servidor PostgreSQL não implementa a instrução OPEN para cursores; o cursor é considerado aberto quando é declarado. Entretanto, o ECPG — Embedded SQL in C, o pré-processador para SQL incorporado do PostgreSQL, fornece suporte às convenções de cursor do padrão SQL, incluindo as que envolvem as instruções DECLARE e OPEN.

A estrutura de dados do servidor subjacente a um cursor aberto é chamada de portal. Os nomes dos portais são expostos no protocolo do cliente: um cliente pode buscar linhas diretamente de um portal aberto, se souber o nome do portal. Ao criar um cursor com o comando DECLARE, o nome do portal é o mesmo que o nome do cursor.

Podem ser vistos todos os cursores disponíveis consultando a visão do sistema pg_cursors.

Exemplo

Para declarar um cursor:

DECLARE liahona CURSOR FOR SELECT * FROM films;

Veja o comando FETCH para obter mais exemplos de uso de cursor.

Conformidade

O padrão SQL permite cursores apenas em SQL incorporado e em módulos. O PostgreSQL permite que os cursores sejam usados interativamente.

Segundo o padrão SQL, as alterações feitas em cursores insensíveis por instruções UPDATE ... WHERE CURRENT OF e DELETE ... WHERE CURRENT OF são visíveis neste mesmo cursor. O PostgreSQL trata estas instruções como as demais instruções de alteração de dados, porque também não são visíveis em cursores insensíveis.

Os cursores binários são uma extensão do PostgreSQL.

Consulta

As informações sobre os cursores disponíveis no momento podem ser consultadas através da visão do sistema pg_cursors.

Veja também

CLOSE, FETCH, MOVE