2014-03-29 168 views
0

我有一个表Tag(ID,名称,描述,isAccepted),“检查约束被一些行违反” 添加检查约束

Content(ID,文本,日期,ID用户→用户,则contentType)

TagQuestion(idQuestion→内容,IDTAG→标签)

,我想确保一个具体的问题只有5个或更少的相关标签(类似的StackOverflow)

所以,I C reated功能:

CREATE FUNCTION can_insert_tag_question(integer) RETURNS boolean 
    LANGUAGE plpgsql 
    AS $_$ 
    BEGIN 
    IF EXISTS (SELECT "idQuestion" FROM "TagQuestion" WHERE "idQuestion" = $1 GROUP BY "idQuestion" HAVING COUNT("idTag") <= 4) 
    THEN 
     RETURN TRUE; 
    ELSIF NOT EXISTS (SELECT "idQuestion" FROM "TagQuestion" WHERE "idQuestion" = $1) 
    THEN 
     RETURN TRUE; 
    ELSE 
     RETURN FALSE; 
    END IF; 
    END; 
$_$; 

TagQuestion尝试添加CHECK约束,以验证它是否可以插入:

ALTER TABLE "public"."TagQuestion" ADD CONSTRAINT "valid_tag" CHECK (can_insert_tag_question("idQuestion")) 

,但我得到一个错误说:

ERROR: check constraint "valid_tag" is violated by some row 

什么意思是不是?我该如何解决它?

回答

1

这意味着你的检查约束正在工作。它可以是简单的:

create function can_insert_tag_question(_id integer) 
returns boolean as $$ 
    with s as (
     select 1 
     from "TagQuestion" 
     where id = _id 
     limit 5 
    ) 
    select count(*) < 5 
    from s; 
$$ language sql; 

它也更快,因为没有分组,并为它找到的,而不是在整个表计数5行也将尽快停止扫描表。

+0

我删除了我在'TagQuestion'中的每一行,并再次添加了检查,它工作。不过,我在相同的问题中插入了6个“标签”,它允许我这样做。 –

+0

我取代了你的消化系统,现在它工作了。顺便说一下,它不允许我使用参数名称,不得不像以前那样将它替换为'$ 1'。任何线索为什么? –

+0

@Hugo什么是版本? 'select version()' –

0

这意味着您在表中存在失败约束的现有数据。你可以通过这样做:

select t.* 
from TagQuestion t 
where not can_insert_tag_question("idQuestion")