ᕼello!我认为我有一些棘手的事情:
parent
有child
个人。 child
有一个age
,还有一个标记为appreciated
。
规则:父母不能欣赏两个同龄孩子!
我的问题是:如何执行此规则?
当前架构:
CREATE TABLE parent (
id SERIAL PRIMARY KEY,
name VARCHAR(50) NOT NULL
);
CREATE TABLE child (
id SERIAL PRIMARY KEY,
parent INTEGER REFERENCES parent(id) NOT NULL,
name VARCHAR(50) NOT NULL,
age INTEGER NOT NULL,
appreciated BOOLEAN NOT NULL
);
将一些值放入:
INSERT INTO parent(name) VALUES
('bob'), -- assume bob's id = 0
('mary'); -- assume mary's id = 1
INSERT INTO child(parent, name, age, appreciated) VALUES
(0, 'child1', 10, FALSE), -- Bob has children 1, 2, 3
(0, 'child2', 10, FALSE),
(0, 'child3', 15, FALSE),
(1, 'child4', 20, FALSE), -- Mary has children 4, 5, 6
(1, 'child5', 20, FALSE),
(1, 'child6', 10, FALSE);
到目前为止一切都很好。没有孩子受到赞赏,这总是有效的。
允许玛丽欣赏孩子6:
UPDATE child SET appreciated=TRUE WHERE name='child6';
鲍勃被允许欣赏child2。 child2与child6(已被欣赏)的年龄相同,但child6不是Bob的孩子。
UPDATE child SET appreciated=TRUE WHERE name='child2';
Bob现在无法欣赏child1。这个child1与child2的年龄相同,child2已经被赞赏了。
UPDATE child SET appreciated=TRUE WHERE name='child2'; -- This needs to FAIL!
如何执行此类约束?我对各种解决方案持开放态度,但修改通用模式不是一种选择。
提前致谢!
答案 0 :(得分:3)
UNIQUE
部分索引如何:
CREATE UNIQUE INDEX ON child(parent,age) WHERE appreciated;
所以每一对parent
,age
都必须是唯一的,但只有在被尊重的孩子被考虑时才会这样。
答案 1 :(得分:1)
您可能希望使用在插入/更新之前激活的触发器,如果不满足您创建的约束,则会失败。 我想它应该像
create trigger <trigger_name>
before insert or update on <table_name>
for each row
declare
dummy number;
begin
select count(*)
into dummy
from <table_name>
where (appreciated=TRUE and :new.child = child and :new.age = age);
if dummy > 0 then
raise_application_error(-20001,'Too many appreciated children');
end if;
end;
答案 2 :(得分:0)
我想要做的最简单的事情是向父模型添加一个感恩(?)== false的标志,当child.appreciated == true {parent.grateful == true}
检查作用于child.appreciated的函数中parent.grateful的值。 如果parent.grateful == true 返回&#34;抱歉,这位家长已表示感谢。&#34; 大声笑这是一个有趣的概念。祝好运。 :)