当我使用重写规则将插入到一个表中拆分为插入到其他两个表中时,其中一个插入的值默认为 nextval('some_sequence'),并且两个表的序列相同,那么插入的默认值在两张桌子。这可能是由于重写规则的简单文本替换。相反,我希望首先解析默认值,然后将相同的值写入两个表。
这是一个示例(您可能猜到了,我正在尝试使用规则实现专业化/泛化):
-- 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;
特定于第一类儿童的数据保存在
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)
);
接下来,我定义了一个视图 Children1,它连接了上面的两个表(我通过明确说明 PostgreSQL 根据文档定义视图所做的事情来重写视图)
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;
最后是我遇到问题的重写规则:
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');
);
尝试插入数据
insert into Children1 (attribute1, attribute2)
values ('a1', 'a2'),
('b1', 'b2');
产生错误消息
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".
解决此问题的一种方法是将重写规则的第二个插入替换为
insert into Partial_Children1(id, attribute2, type)
select p.id, new.attribute2, p.type
from Parents p
where p.attribute1 = new.attribute1
但这依赖于属性 1 的唯一性,我不想强加。另一种解决方案是首先将值插入到临时表中,然后从那里选择两次以插入到两个表中。但由于性能原因,我不喜欢它。
有谁知道如何在两个表中获得相同的默认值(仅使用规则而不是触发器)?