Postgresql中插入的条件规则
我的问题与我遇到的postgresql问题有关。 我想修改包含新闻组(如论坛)的数据库。其消息描述一棵树,并存储在如下表中:Postgresql中插入的条件规则,sql,postgresql,conditional,rule,Sql,Postgresql,Conditional,Rule,我的问题与我遇到的postgresql问题有关。 我想修改包含新闻组(如论坛)的数据库。其消息描述一棵树,并存储在如下表中: \d messages Table « public.messages » Column | Type | Modifiers -----------+------------------
\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 |
(我把输出翻译成法语,希望没有增加误解)
Title是消息标题,datemsg的时间戳、作者和文本非常明确,idgroup是找到消息的讨论组标识符,msgfather是该消息的另一条消息。
我想在insert上实现的规则是防止用户将答案添加到与其父组不同的组的邮件中(如果该组有答案,则新的讨论将以没有父组的新邮件开始)
现在我有这样的看法:
\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);
即使有了这条新规则,人们仍然可以回答一条消息并在另一组中设置此答案
我也试图通过添加来更改INSU消息规则,其中NEW.msgfather为NULL
,但是当我尝试添加消息时,出现了一个错误,即在newmessage视图中插入时找不到任何规则
那么,如何实现我想做的事情呢?用扳机?(我不知道如何使用postgresql执行此操作)。首先为
(idmessage,idgroup)
创建一个唯一索引:
下面的msgfather\u idgroup\u fkey
需要此约束
因为外键约束要求匹配唯一索引和
如果没有它,将出现错误:对于引用的表“messages”
,没有与给定键匹配的唯一约束
然后添加自引用外键:
alter table messages add constraint msgfather_idgroup_fkey
foreign key (msgfather,idgroup) references messages(idmessage,idgroup);
顺便说一下:
- 将
添加到notnull
和datemsg
列中author
插入到newmessage(title、text、msgfather、idgoup)值('integrity test'、'this message not insert as msgfather not in idgroup 4'、'1'、'4')
。是否可以再次检查此约束是否已成功创建。这应该是不可能的-我已经在我的系统中测试过了。是的,似乎约束没有被创建。这是\d messages
的输出:我是否应该修改一个现有约束messages\u msgpere\u fkey,它可能与新约束冲突?非常感谢您的回答,我感谢您的帮助。我无法更改表消息添加约束msgfather\u idgroup\fkey外键(msgfather,idgroup)引用消息(idmessage,idgroup)代码>。我有以下错误错误:«消息»表上的insert或update指令违反外键«msgfather\U idgroup\U fkey»详细信息:«消息»表中不存在键(msgfather,idgroup)=(1,2)。
在添加此约束之前,您首先需要使数据一致。您可以使用select messages.idmessage from messages left将不一致的记录作为父亲加入到消息中。msgfather=fathers.idmessage where messages.idgroupfathers.idgroup
alter table messages add constraint msgfather_idgroup_fkey
foreign key (msgfather,idgroup) references messages(idmessage,idgroup);