COMMIT가 PostgreSQL 9.5의 익명 plgpsql 함수 내에서 작동합니까?


8

익명의 plpgsql 코드 블록 내에서 루프를 사용하여 분할 할 여러 테이블로 많은 수의 큰 파일을 가져오고 있습니다 $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

이 전체 프로세스는 약 15 시간이 걸리며 가져 오기 오류가 발생하면 모든 가져 오기가 롤백되지 않기를 바랍니다.

IIRC COMMIT는 저장된 함수 내에서 작동하지 않습니다. bc 전체 함수는 단일 트랜잭션으로 처리됩니다.

에 대한 설명서에서$do$

코드 블록은 매개 변수가없는 함수의 본문 인 것처럼 처리되어 void를 반환합니다. 한 번만 구문 분석되고 실행됩니다.

나는 이것이 전체 $do$가 하나의 트랜잭션이므로 블록 내에서 커밋이 작동하지 않는다는 것을 의미한다고 가정합니다 . 제가 맞습니까?


1
BEGIN또는 COMMIT함수 본문에서 시도하십시오 . 허용되지 않기 때문에 예외가 발생합니다 (불가능).
Erwin Brandstetter 1

답변:


9

아니,

plpgsql함수 (또는 익명 블록) 내에서 트랜잭션을 제어 할 수 없습니다 .

블록 외부에서 트랜잭션을 생성 할 수있는 유일한 옵션은 다음과 같습니다.

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 BLOCKS는을 반환하는 함수와 동일한 효과를 갖습니다 void.

문서에서 자세한 내용을 참조하십시오.


이것이 사실인지 우리는 알고 있습니까? 수백 번 반복 해야하는 기능이 있습니다. 첫 번째 루프는 7 번째 시간이 1 시간에 가까운 후 2 초가 걸리고 10 번째 루프 후에는 아무것도 보지 못했습니다.
Dennis Bauszus

1

"DO"블록 (또는 함수) 내 (Postgresql 버전 11 이하) 내에서 커밋하는 유일한 솔루션은 동일한 서버에 대한 dblink 연결을 사용하여 쿼리를 실행하는 것입니다. 변수와 임시 객체 가시성을 명심하십시오.

dblink에 대한 추가 정보 "DO"블록 내부에서 Postgresql-11 트랜잭션 제어로 시작하는 것은 "DO 블록"이 다른 트랜잭션 내에서 실행되지 않는 동안 사용할 수 있습니다.


postgresql.org/docs/11/sql-do.html 은 '트랜잭션 제어문은 DO가 자체 트랜잭션에서 실행되는 경우에만 허용됩니다'라고 말합니다. 물론 9.5에서는 그렇지 않았습니다. dblink당신 과 함께 OTOH 는 다른 거래를 열 것이므로 COMMIT, 실수하지 않으면 전화가 전화 거래에 영향을 미치지 않습니다.
dezso

내 잘못이야. "DO"내의 트랜잭션 제어는 Postgresql-11에서 도입되었습니다. 10.4가 여전히 작동하지 않는지 확인합니다.
Dzhureedzh 2017

@dezso 이것을 지적 해 주셔서 감사합니다. PG11 서버에서도 dblink 방법을 사용하고있었습니다.
Dzhureedzh 2016
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.