我目前正在学习SQL,并且我有一个关于我必须为练习创建的约束的问题。
鉴于2表:
CREATE TABLE A (
a1 integer PRIMARY KEY,
a2 integer CHECK (a2>10))
CREATE TABLE B (
b1 integer PRIMARY KEY, b2 integer))
和A和B之间的多对多关系表
CREATE TABLE R (
rID integer PRIMARY KEY,
a1ID integer REFERENCES A (a1),
b1ID integer REFERENCES B (b1))
我想在表B上创建一个约束,这样:当添加一个新的B实例时,应该至少有5个,最多10个A与B相关的实例。
我就这样做了:
1)插入B的触发器:
CREATE triggerA BEFORE INSERT ON B
EXECUTE PROCEDURE upCons();
2)创建一个函数,检查与B相关的A实例的数量:
这是我的问题,我可以通过这样做来计算R的实例数吗?
CREATE FUNCTION upCons() RETURN trigger AS $$
DECLARE x integer;
BEGIN
SELECT count(rID) INTO x FROM R;
IF (x<5 OR x>10) THEN RAISE EXCEPTION 'insert condition not met';
END IF;
END; LANGUAGE 'plpgsql';
或者我通过计算关系中A的实例来做同样的事。
这是解决问题的好方法吗?我应该采用不同的方式吗?从
开始是正确的答案 0 :(得分:1)
我想在表B上创建一个约束,以便:当一个新实例时 添加B,应该至少有5个,最多10个 存在与B有关。
这种约束似乎是不合理的(或者甚至是不可能的),因为在将条目插入B(或A)时,不存在任何已经引用新条目的关系。引用条目(使用外键约束)要求条目本身已存在于正确的表中。根据你的触发器,如果你在R中没有足够的关系,你就不能在B中插入任何东西。因此你已经有效地使你的表B和R只读,因为你的触发器和表R拒绝了表B插入外键约束的插入需要对表B的任何引用已存在于表B中。
答案 1 :(得分:0)
IF (x<5 AND x>10) THEN RAISE EXCEPTION 'insert condition not met';
这应该是OR而不是AND,对吧?