更新问题的SQL约束

时间:2014-01-23 11:06:58

标签: sql postgresql constraints

我目前正在学习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的实例来做同样的事。

这是解决问题的好方法吗?我应该采用不同的方式吗?从

开始是正确的

2 个答案:

答案 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,对吧?