Liệu một CAMIT có hoạt động trong một hàm plgpsql ẩn danh trong PostgreQuery 9.5 không?


8

Tôi đang nhập một số lượng lớn các tệp lớn vào một số bảng để được phân vùng bằng các vòng lặp trong một khối mã plpgsql ẩn danh $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

Toàn bộ quá trình này sẽ mất khoảng 15 giờ và tôi hy vọng rằng tất cả các lần nhập sẽ không được khôi phục nếu có lỗi nhập vào một lúc nào đó.

IIRC COMMITkhông hoạt động trong các chức năng được lưu trữ bc, toàn bộ chức năng được coi là một giao dịch.

Từ tài liệu cho$do$

Khối mã được xử lý như thể nó là phần thân của hàm không có tham số, trả về khoảng trống. Nó được phân tích cú pháp và thực hiện một lần duy nhất.

Tôi cho rằng điều này có nghĩa là toàn bộ $do$là một giao dịch và do đó, các cam kết trong khối sẽ không hoạt động. Tôi có đúng không?


1
Hãy thử BEGINhoặc COMMITtrong cơ thể chức năng. Bạn sẽ có một ngoại lệ, vì điều đó không được phép (không thể).
Erwin Brandstetter

Câu trả lời:


9

Không,

Bạn không thể kiểm soát một giao dịch bên trong một plpgsqlchức năng (hoặc khối ẩn danh).

Tùy chọn duy nhất mà bạn có nó tạo ra một giao dịch bên ngoài khối, ví dụ:

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 BLOCKScó tác dụng tương tự như chức năng trả về void.

Xin vui lòng, xem thêm tại tài liệu:


Chúng ta có biết liệu đây vẫn là trường hợp? Tôi có một chức năng cần lặp vài trăm lần. Vòng lặp đầu tiên mất 2 giây sau vòng 7 gần một giờ và tôi chưa thấy gì sau vòng lặp thứ 10.
Dennis Bauszus

1

Giải pháp duy nhất để cam kết trong các khối "DO" (hoặc chức năng) (đối với phiên bản Postgresql nhỏ hơn 11) là sử dụng kết nối dblink đến cùng một máy chủ để thực hiện các truy vấn của bạn ở đó. Chỉ cần ghi nhớ các biến và các đối tượng tạm thời hiển thị.

thêm thông tin về dblink Bắt đầu với kiểm soát giao dịch Postgresql-11 từ bên trong khối "DO" khả dụng trong khi "DO-block" không chạy trong giao dịch khác.


postgresql.org/docs/11/sql-do.html tuyên bố 'Các câu lệnh kiểm soát giao dịch chỉ được phép nếu DO được thực thi trong giao dịch của chính nó.' Điều này tất nhiên không đúng với 9.5. OTOH với dblinkbạn sẽ mở một giao dịch khác, vì vậy COMMITcuộc gọi của bạn sẽ không ảnh hưởng đến giao dịch cuộc gọi, nếu tôi không nhầm.
dezso

Lỗi của tôi. Kiểm soát giao dịch trong "DO" đã được giới thiệu trong Postgresql-11. Tôi chỉ kiểm tra trên 10,4 vẫn không hoạt động.
Dzhureedzh

@dezso Cảm ơn bạn đã chỉ cho tôi điều này, tôi đã sử dụng phương pháp dblink ngay cả trên các máy chủ PG11.
Dzhureedzh
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.