(Lưu ý:. Cập nhật với câu trả lời thông qua dưới đây)PostgreSQL: UPDATE ngụ ý di chuyển trên phân vùng
Đối với một PostgreSQL 8.1 (hoặc mới hơn) bảng phân vùng, làm thế nào để xác định một UPDATE
kích hoạt và thủ tục để "di chuyển" một bản ghi từ phân vùng này sang phân vùng khác, nếu UPDATE
ngụ ý một sự thay đổi đối với trường ràng buộc xác định phân đoạn phân vùng?
Ví dụ, tôi đã là một bảng hồ sơ phân chia thành các hồ sơ hoạt động và không hoạt động như sau:
create table RECORDS (RECORD varchar(64) not null, ACTIVE boolean default true);
create table ACTIVE_RECORDS (check (ACTIVE)) inherits RECORDS;
create table INACTIVE_RECORDS (check (not ACTIVE)) inherits RECORDS;
Các INSERT
kích hoạt và làm việc chức năng cũng như: hồ sơ hoạt động mới được đưa vào một bảng, và mới hồ sơ không hoạt động trong một cái khác. Tôi muốn UPDATE
s vào trường ACTIVE để "di chuyển" một bản ghi từ một bảng con cháu này sang bảng con khác, nhưng tôi gặp phải lỗi cho thấy điều này có thể không thực hiện được.
Kích hoạt đặc điểm kỹ thuật và thông báo lỗi:
pg=> CREATE OR REPLACE FUNCTION record_update()
RETURNS TRIGGER AS $$
BEGIN
IF (NEW.active = OLD.active) THEN
RETURN NEW;
ELSIF (NEW.active) THEN
INSERT INTO active_records VALUES (NEW.*);
DELETE FROM inactive_records WHERE record = NEW.record;
ELSE
INSERT INTO inactive_records VALUES (NEW.*);
DELETE FROM active_records WHERE record = NEW.record;
END IF;
RETURN NULL;
END;
$$
LANGUAGE plpgsql;
pg=> CREATE TRIGGER record_update_trigger
BEFORE UPDATE ON records
FOR EACH ROW EXECUTE PROCEDURE record_update();
pg=> select * from RECORDS;
record | active
--------+--------
foo | t -- 'foo' record actually in table ACTIVE_RECORDS
bar | f -- 'bar' record actually in table INACTIVE_RECORDS
(2 rows)
pg=> update RECORDS set ACTIVE = false where RECORD = 'foo';
ERROR: new row for relation "active_records" violates check constraint "active_records_active_check"
Chơi với các thủ tục kích hoạt (trở về NULL và vân vân) gợi ý với tôi rằng các hạn chế được kiểm tra, và các lỗi nêu ra, trước khi kích hoạt của tôi được gọi, có nghĩa là cách tiếp cận hiện tại của tôi sẽ không hoạt động. Điều này có thể được nhận để làm việc?
UPDATE/ĐÁP
Dưới đây là thủ tục UPDATE
cò tôi đã kết thúc sử dụng, thủ tục tương tự được gán cho mỗi của phân vùng. Tín dụng là hoàn toàn để Bell, mà câu trả lời đã cho tôi cái nhìn sâu sắc chìa khóa để kích hoạt trên các phân vùng:
CREATE OR REPLACE FUNCTION record_update()
RETURNS TRIGGER AS $$
BEGIN
IF ((TG_TABLE_NAME = 'active_records' AND NOT NEW.active)
OR
(TG_TABLE_NAME = 'inactive_records' AND NEW.active)) THEN
DELETE FROM records WHERE record = NEW.record;
INSERT INTO records VALUES (NEW.*);
RETURN NULL;
END IF;
RETURN NEW;
END;
$$
LANGUAGE plpgsql;
"dụ" bạn là không đầy đủ: thiếu định nghĩa cho "partitioned_records"; bạn xác định trình kích hoạt cho "partitioned_records" nhưng chọn từ và cập nhật "RECORDS". –
@Milen, cảm ơn - lỗi cut'n'paste. Sẽ khắc phục. – pilcrow
Điểm của việc sử dụng phân vùng trong ngữ cảnh này khi bạn có thể sử dụng chỉ mục một phần là gì? – kalu