AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • Início
  • system&network
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • Início
  • system&network
    • Recentes
    • Highest score
    • tags
  • Ubuntu
    • Recentes
    • Highest score
    • tags
  • Unix
    • Recentes
    • tags
  • DBA
    • Recentes
    • tags
  • Computer
    • Recentes
    • tags
  • Coding
    • Recentes
    • tags
Início / dba / Perguntas / 52968
Accepted
A-K
A-K
Asked: 2013-11-08 11:02:28 +0800 CST2013-11-08 11:02:28 +0800 CST 2013-11-08 11:02:28 +0800 CST

Como posso manter um conjunto de resultados sem manter a transação aberta?

  • 772

A documentação a seguir descreve como ver o refcursor retornado de uma função, aqui , assim:

    CREATE FUNCTION reffunc(refcursor) RETURNS refcursor AS '
BEGIN
    OPEN $1 FOR SELECT col FROM test;
    RETURN $1;
END;
' LANGUAGE plpgsql;

BEGIN;
SELECT reffunc('funccursor');
FETCH ALL IN funccursor;
COMMIT;

Isso funciona para mim. Porém, se eu quiser manter os resultados na minha tela, tenho que manter a transação aberta. Quando executo o COMMIT, meu conjunto de resultados é descartado. Quando executo FETCH e COMMIT ao mesmo tempo, o primeiro conjunto de resultados é descartado.

Existe uma maneira de confirmar a transação, mas manter o conjunto de resultados? A versão do PgAdmin é 1.18.1.

postgresql pgadmin
  • 2 2 respostas
  • 7818 Views

2 respostas

  • Voted
  1. Best Answer
    Daniel Vérité
    2013-11-08T17:54:58+08:002013-11-08T17:54:58+08:00

    Quando um cursor é definido no nível SQL com DECLARE , existe uma opção WITH HOLDque faz com que ele continue existindo após o commit da transação atual. Citando o documento:

    WITH HOLD especifica que o cursor pode continuar a ser usado depois que a transação que o criou for confirmada com sucesso

    Por outro lado, um refcursor aberto por uma função plpgsql é fechado ao final da transação. Citando o documento plpgsql :

    Todos os portais são implicitamente fechados no final da transação. Portanto, um valor refcursor é utilizável para referenciar um cursor aberto somente até o final da transação.

    Para criar um cursor em uma função plpgsql que pode ser usada fora de sua transação "pai", é apenas uma questão de sintaxe. Você deseja a implementação SQL de um cursor, não a variante plpgsql. Para isso, EXECUTEdeve ser usado.

    Como exemplo, aqui está o esqueleto de uma função semelhante à sua, mas usando cursores de nível SQL que sobrevivem à transação:

    CREATE FUNCTION dyncursor(name text) RETURNS VOID AS
    $$
    DECLARE
      query text;
    BEGIN
      query='SELECT 1 as col1, 2 as col2'; -- sample query
      EXECUTE 'DECLARE ' || quote_ident(name) || ' CURSOR WITH HOLD FOR ' || query;
    END
    $$ language plpgsql;
    

    Demonstração:

    teste => início;
    teste=> selecione dynccursor('foo');
     cursor dinâmico
    -----------
    
    (1 linha)
    teste=> confirmar;
    test=> busca tudo de foo;
     col1 | col2
    ------+------
        1 | 2
    (1 linha)
    teste=> fechar foo;
    FECHAR CURSOR
    
    • 8
  2. Erwin Brandstetter
    2013-11-08T15:35:57+08:002013-11-08T15:35:57+08:00

    pgAdmin é apenas uma GUI. Em grande parte irrelevante para esta questão. Acontece que uma ou mais sessões são vinculadas a uma janela do editor SQL e terminam quando a janela é fechada.

    Se você deseja manter a transação aberta, apenas não COMMIT(ou ROLLBACK) ainda.

    Se você realmente deseja "manter" o conjunto de resultados, escreva-o em uma table- possivelmente uma tabela TEMPORARYouUNLOGGED se você não precisar persistir permanentemente. Uma tabela temporária vive e morre com a sessão por padrão.

    SQL e PL/pgSQL são bastante rígidos com seu sistema de tipos e algumas coisas que parecem possíveis não foram implementadas (ainda). Mas o que você está tentando fazer provavelmente pode ser resolvido sem cursores. Se você precisar fornecer um nome de tabela para uma função dinamicamente, use um tipo de retorno polimórfico encadeado a um parâmetro de entrada:

    CREATE OR REPLACE FUNCTION f_dynamic_select(_tbl anyelement)
     RETURNS SETOF anyelement AS
    $func$
    BEGIN
    
    RETURN QUERY EXECUTE
    'SELECT * FROM ' || pg_typeof(_tbl);
    
    END
    $func$ LANGUAGE plpgsql;
    

    Ligar:

    SELECT * FROM  f_dynamic_select(NULL::my_schema.my_table)
    

    Este formulário é automaticamente seguro contra injeção de SQL, pois pg_typeof()retorna um regtypevalor que é escapado automaticamente (se necessário) quando é convertido automaticamente textdurante a concatenação de strings.

    Eu escrevi uma resposta intimamente relacionada lidando com tipos polimórficos ontem. Tem mais explicações e links:
    Inserir valores de uma variável de registro em uma tabela

    Normalmente , um simples e simples SELECTfaria o trabalho. É uma condição rara que os nomes das tabelas sejam fornecidos dinamicamente.

    SELECT * FROM my_schema.my_table
    
    • 4

relate perguntas

  • Posso ativar o PITR depois que o banco de dados foi usado

  • Práticas recomendadas para executar a replicação atrasada do deslocamento de tempo

  • Os procedimentos armazenados impedem a injeção de SQL?

  • Sequências Biológicas do UniProt no PostgreSQL

  • Qual é a diferença entre a replicação do PostgreSQL 9.0 e o Slony-I?

Sidebar

Stats

  • Perguntas 205573
  • respostas 270741
  • best respostas 135370
  • utilizador 68524
  • Highest score
  • respostas
  • Marko Smith

    Como fazer a saída do sqlplus aparecer em uma linha?

    • 3 respostas
  • Marko Smith

    Selecione qual tem data máxima ou data mais recente

    • 3 respostas
  • Marko Smith

    Como faço para listar todos os esquemas no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Conceder acesso a todas as tabelas para um usuário

    • 5 respostas
  • Marko Smith

    Listar todas as colunas de uma tabela especificada

    • 5 respostas
  • Marko Smith

    Como usar o sqlplus para se conectar a um banco de dados Oracle localizado em outro host sem modificar meu próprio tnsnames.ora

    • 4 respostas
  • Marko Smith

    Como você mysqldump tabela (s) específica (s)?

    • 4 respostas
  • Marko Smith

    Listar os privilégios do banco de dados usando o psql

    • 10 respostas
  • Marko Smith

    Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL?

    • 4 respostas
  • Marko Smith

    Como faço para listar todos os bancos de dados e tabelas usando o psql?

    • 7 respostas
  • Martin Hope
    Stéphane Como faço para listar todos os esquemas no PostgreSQL? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh Por que o log de transações continua crescendo ou fica sem espaço? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland Listar todas as colunas de uma tabela especificada 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney O MySQL pode realizar consultas razoavelmente em bilhões de linhas? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx Como posso monitorar o andamento de uma importação de um arquivo .sql grande? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison Como você mysqldump tabela (s) específica (s)? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    pedrosanta Listar os privilégios do banco de dados usando o psql 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas Como posso cronometrar consultas SQL usando psql? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas Como inserir valores em uma tabela de uma consulta de seleção no PostgreSQL? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas Como faço para listar todos os bancos de dados e tabelas usando o psql? 2011-02-18 00:45:49 +0800 CST

Hot tag

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • Início
  • Perguntas
    • Recentes
    • Highest score
  • tag
  • help

Footer

AskOverflow.Dev

About Us

  • About Us
  • Contact Us

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve