我的问题是我遇到的postgresql问题。 我想修改一个包含类似新闻组的论坛的数据库。它的消息描述了一棵树,并存储在一个表中,如下所示:
\d messages
Table « public.messages »
Column | Type | Modifiers
-----------+-----------------------------+------------------------------------------------------------------
idmessage | integer | not NULL By default, nextval('messages_idmessage_seq'::regclass)
title | character varying(50) | not NULL
datemsg | timestamp without time zone | By default, ('now'::text)::timestamp without time zone
author | character varying(10) | By default, "current_user"()
text | text | not NULL
idgroup | integer | not NULL
msgfather | integer |
(我翻译了法语的输出,希望我没有添加误解)
标题是消息标题,datemsg其时间戳,作者和文本非常明确,idgroup是发现消息的讨论组标识符,msgfather是此消息的另一个消息。 我想在插入时实现的规则是关于阻止用户添加一个与父亲不同的组的消息的答案(如果它有一个,因为新的讨论以一个没有父节点的新消息开始)。
现在我有了这个观点:
\d newmessage
View « public.newmessage »
Column | Type | Modifiers
-----------+-----------------------+---------------
idmessage | integer |
title | character varying(50) |
text | text |
idgroup | integer |
msgfather | integer |
View definition :
SELECT messages.idmessage, messages.title, messages.text, messages.idgroup, messages.msgfather
FROM messages;
Rules :
ins_message AS
ON INSERT TO newmessage DO INSTEAD INSERT INTO messages (title, text, idgroup, msgfather)
VALUES (new.title, new.text, new.idgroup, new.msgfather)
我无法更改视图或表格,因为人们已经使用了数据库,因此我认为我必须使用规则或触发器。
我尝试将以下规则添加到视图中,没有预期效果:
CREATE OR REPLACE RULE ins_message_answer AS ON INSERT TO newmessage WHERE NEW.msgfather IS NOT NULL DO INSTEAD INSERT INTO messages( title, text, idgroup, msgfather) VALUES ( NEW.title, NEW.text, (SELECT idgroup FROM messages WHERE idmessage=new.msgfather), NEW.msgfather);
即使有了这条新规则,人们仍然可以回复邮件并在另一组中设置此答案。
我也尝试通过添加WHERE NEW.msgfather IS NULL
来更改ins_message规则,但是当我尝试添加消息时,我在新消息视图中的插入时发现没有找到规则的错误。
那么如何实现我想做的事情呢?有触发器吗? (我不知道怎么用postgresql做一个。)
答案 0 :(得分:2)
首先为(idmessage, idgroup)
创建唯一索引:
alter table messages add constraint messages_idmessage_idgroup_key
unique (idmessage, idgroup);
以下msgfather_idgroup_fkey
需要此约束
因为外键约束需要匹配唯一索引和
没有它,就会有ERROR: there is no unique constraint matching given keys for referenced table "messages"
。
然后添加自引用外键:
alter table messages add constraint msgfather_idgroup_fkey
foreign key (msgfather,idgroup) references messages(idmessage,idgroup);
顺便说一下:
将NOT NULL
添加到datemsg
和author
列;