Um COMMIT funciona dentro de uma função anônima plgpsql no PostgreSQL 9.5?


8

Estou importando um grande número de arquivos grandes para um número de tabelas a serem particionadas usando loops dentro de um bloco de código plpgsql anônimo $do$.

$do$
BEGIN
    FOR yyyy in 2012..2016 THEN 
        EXECUTE $$COPY table$$||yyyy||$$ FROM 'E:\data\file$$||yyyy||$$.csv DELIMITER ',' CSV;$$;
    END LOOP;
END;
$do$ LANGUAGE plpgsql

Todo esse processo deve levar cerca de 15 horas e espero que todas as importações não sejam revertidas se houver um erro de importação em algum momento.

O IIRC COMMITnão funciona nas funções armazenadas, pois a função inteira é tratada como uma única transação.

A partir da documentação para$do$

O bloco de código é tratado como se fosse o corpo de uma função sem parâmetros, retornando nulo. É analisado e executado uma única vez.

Estou assumindo que isso significa que toda a $do$transação é uma e, portanto, as confirmações dentro do bloco não funcionarão. Estou correcto?


11
Tente BEGINou COMMITno corpo da função. Você receberá uma exceção, porque isso não é permitido (não é possível).
Erwin Brandstetter

Respostas:


9

Não,

Você não pode controlar uma transação dentro de uma plpgsqlfunção (ou bloco anônimo).

A única opção que você tem para criar uma transação fora do bloco, por exemplo:

BEGIN;

DO $$
  -- function stuff

  -- but if you use a exception, you will force a rollback
  RAISE EXCEPTION 'message';
$$ LANGUAGE 'plpgsql';

COMMIT; -- OR ROLLBACK

BTW, DO BLOCKStem o mesmo efeito que funciona quem retorna void.

Por favor, veja mais no documento:


Sabemos se esse ainda é o caso? Eu tenho uma função que precisa repetir várias centenas de vezes. O primeiro loop leva 2 segundos depois que o 7º está perto de uma hora e eu não vi nada após o 10º loop.
Dennis Bauszus

1

A única solução a ser confirmada nos blocos "DO" (ou funções) (para a versão Postgresql menor que 11) é usar a conexão dblink no mesmo servidor e executar suas consultas lá. Lembre-se da visibilidade de variáveis ​​e objetos temporários.

mais informações sobre dblink Iniciando com o controle de transações Postgresql-11 de dentro do bloco "DO" está disponível enquanto o "bloco DO" não está sendo executado em outra transação.


postgresql.org/docs/11/sql-do.html afirma 'As instruções de controle de transação são permitidas apenas se o DO for executado em sua própria transação.' Obviamente, isso não era verdade com o 9.5. OTOH com dblinkvocê abrirá outra transação, para que sua COMMITligação não afete a transação, se não me engano.
Dezso

Foi mal. O controle de transações no "DO" foi introduzido no Postgresql-11. Acabei de verificar 10.4 ainda não está funcionando.
Dzhureedzh

@dezso Obrigado por me indicar isso, eu estava usando o método dblink, mesmo em servidores PG11.
Dzhureedzh 25/04/19
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.