2014-03-29 205 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")