COPY
tệp vào một bảng tạm thời và cập nhật bảng thực tế từ đó. Như:
CREATE TEMP TABLE tmp_x (id int, apple text, banana text); -- but see below
COPY tmp_x FROM '/absolute/path/to/file' (FORMAT csv);
UPDATE tbl
SET banana = tmp_x.banana
FROM tmp_x
WHERE tbl.id = tmp_x.id;
DROP TABLE tmp_x; -- else it is dropped at end of session automatically
Nếu bảng đã nhập khớp với bảng được cập nhật chính xác, điều này có thể thuận tiện:
CREATE TEMP TABLE tmp_x AS SELECT * FROM tbl LIMIT 0;
Tạo một bảng tạm thời trống phù hợp với cấu trúc của bảng hiện có mà không có ràng buộc.
Đặc quyền
Lên đến Postgres 10, SQL COPY
yêu cầu đặc quyền của siêu người dùng cho việc này.
Trong Postgres 11 trở lên, cũng có một số vai trò được xác định trước (trước đây là "vai trò mặc định") để cho phép nó. Hướng dẫn sử dụng:
COPY
chỉ cho phép đặt tên cho một tệp hoặc lệnh đối với người dùng cấp trên cơ sở dữ liệu hoặc người dùng được cấp một trong các vai tròpg_read_server_files
,pg_write_server_files
hoặcpg_execute_server_program
[...]
psql lệnh meta \copy
hoạt động cho bất kỳ vai trò db nào. Hướng dẫn sử dụng:
Thực hiện sao chép giao diện người dùng (máy khách). Đây là một hoạt động chạy anSQL
COPY
nhưng thay vì máy chủ đọc hoặc ghi tệp chỉ định, psql đọc hoặc ghi tệp và định tuyến cơ sở dữ liệu giữa máy chủ và hệ thống tệp cục bộ. Điều này có nghĩa là khả năng truy cập tệp và các đặc quyền là của người dùng cục bộ, không phải của máy chủ và không cần có đặc quyền của người dùng siêu cấp SQL.
Phạm vi của các bảng tạm thời được giới hạn trong một phiên của một vai trò duy nhất, vì vậy những điều trên phải được thực thi trong cùng một phiên psql:
CREATE TEMP TABLE ...;
\copy tmp_x FROM '/absolute/path/to/file' (FORMAT csv);
UPDATE ...;
Nếu bạn đang viết kịch bản lệnh này trong một lệnh bash, hãy đảm bảo gói tất cả trong một đơn cuộc gọi psql. Như:
echo 'CREATE TEMP TABLE tmp_x ...; \copy tmp_x FROM ...; UPDATE ...;' | psql
Thông thường, bạn cần lệnh meta \\
để chuyển đổi giữa các lệnh meta psql và lệnh SQL trong psql, nhưng \copy
là một ngoại lệ cho quy tắc này. Hướng dẫn sử dụng lại:
các quy tắc phân tích cú pháp đặc biệt áp dụng cho
\copy
lệnh meta. Không giống như hầu hết các lệnh meta khác, toàn bộ phần còn lại của dòng luôn được coi là đối số của\copy
và không nội suy biến hay mở rộng dấu ngoặc kép nào được thực hiện trong các đối số.
Bảng lớn
Nếu bảng nhập lớn, nó có thể phải trả để tăng temp_buffers
tạm thời cho phiên (điều đầu tiên trong phiên):
SET temp_buffers = '500MB'; -- example value
Thêm chỉ mục vào bảng tạm thời:
CREATE INDEX tmp_x_id_idx ON tmp_x(id);
Và chạy ANALYZE
theo cách thủ công, vì các bảng tạm thời không được autovacuum / tự động phân tích.
ANALYZE tmp_x;
Các câu trả lời liên quan:
- Cách tốt nhất để xóa hàng triệu hàng theo ID
- Làm cách nào để chèn dữ liệu chung vào bảng tạm thời từ các lược đồ khác nhau?
- Làm cách nào để xóa các mục nhập trùng lặp?