Khi tôi sử dụng quy tắc viết lại để tách một chèn vào một bảng thành chèn vào hai bảng khác, nơi một trong các giá trị được chèn vào làm mặc định tiếp theo ('some_sequence ') với cùng một trình tự cho cả hai bảng, sau đó các giá trị mặc định được chèn khác nhau trong hai bảng. Điều này có thể do thay thế văn bản đơn giản bằng quy tắc viết lại. Tôi đã hy vọng thay vào đó giá trị mặc định sẽ được giải quyết đầu tiên và sau đó giá trị tương tự được ghi vào cả hai bảng.Các quy tắc và vấn đề tiếp theo() của PostgreSQL (rất cụ thể về PostgreSQL)
Dưới đây là một ví dụ (như bạn có thể đoán, tôi đang cố gắng để thực hiện chuyên môn hóa/tổng quát sử dụng quy tắc):
-- first and third commands can be skipped if id is defined as serial
create sequence parents_id_seq;
create table Parents(
id integer default(nextval('parents_id_seq')) primary key,
type varchar(50) not null check(type in ('Child1', 'Child2')),
unique (id, type),
attribute1 varchar(50) not null unique check(length(attribute1) > 0)
);
alter sequence parents_id_seq owned by parents.id;
Số liệu cụ thể cho con cái của các loại đầu tiên được lưu giữ trong
create table Partial_Children1(
id integer default(nextval('parents_id_seq')) primary key,
type varchar(50) not null check(type = 'Child1'),
foreign key (id, type) references Parents(id, type),
attribute2 varchar(50) not null check(length(attribute2) > 0)
);
Tiếp theo, tôi đã xác định chế độ xem Children1 tham gia cả hai bảng ở trên (tôi đã viết lại chế độ xem bằng cách nêu rõ những gì PostgreSQL thực hiện để xác định lượt xem theo tài liệu)
create table Children1(
id int default(nextval('parents_id_seq')),
type varchar(50) not null check(type in ('Child1')),
attribute1 varchar(50) not null check(length(attribute1) > 0),
attribute2 varchar(50) not null check(length(attribute2) > 0)
);
create rule "_RETURN" as on select to Children1 do instead
select p.*, c.attribute2
from Parents p
join Partial_Children1 c
on p.id = c.id;
Cuối cùng viết lại quy tắc tôi đang gặp vấn đề với:
create rule ct_i_children1 as
on insert to Children1
do instead (
insert into Parents(attribute1, type)
values(new.attribute1, 'Child1');
insert into Partial_Children1(attribute2, type)
values(new.attribute2, 'Child1');
);
Đang cố gắng để chèn dữ liệu với
insert into Children1 (attribute1, attribute2)
values ('a1', 'a2'),
('b1', 'b2');
mang lại được thông báo lỗi
ERROR: insert or update on table "partial_children1" violates foreign key constraint "partial_children1_id_fkey"
DETAIL: Key (id,type)=(3,Child1) is not present in table "parents".
Một cách để giải quyết việc này đang thay thế chèn thứ hai của quy tắc viết lại bằng
insert into Partial_Children1(id, attribute2, type)
select p.id, new.attribute2, p.type
from Parents p
where p.attribute1 = new.attribute1
nhưng điều này phụ thuộc vào tính duy nhất của thuộc tính1 mà tôi không muốn áp đặt. Một giải pháp khác sẽ là chèn các giá trị đầu tiên vào một bảng tạm thời, và sau đó chọn hai lần từ đó cho các chèn vào hai bảng. Nhưng tôi không thích vì lý do hiệu suất.
Có ai có ý tưởng khác về cách nhận các giá trị mặc định giống nhau trong cả hai bảng (chỉ sử dụng quy tắc và không kích hoạt trình kích hoạt)?
Cảm ơn các liên kết. Họ không giải quyết vấn đề, nhưng ít nhất tôi không cảm thấy cô đơn nữa ;-). Tính năng kế thừa được tích hợp không hoàn toàn cung cấp những gì tôi muốn. –