2013-07-15 18 views
0

我想在這裏得到的是哪個主題已經有4個教室,如果超過了通知並返回null,並且工作。但是當我插入其他主題「2」時,代碼會提出相同的通知,但我這個主題只有1個類。我知道我使用的是「HAVING COUNT(cod_classroom) = 4」,代碼只能得到主題已經有4個教室的內容。我試圖只用這個:「SELECT DISTINCT cod_subject,COUNT(cod_classroom) AS CountOf FROM registration_subject GROUP BY cod_subject」但我不知道如何檢查更多的值。檢查PostgreSQL中每個值都已經超過了觸發器的限制併發出通知

我希望你們都明白我想要什麼,我盡力=)謝謝大家提前

CREATE OR REPLACE FUNCTION quantas() 
     RETURNS trigger AS 
    $BODY$declare qtd record; 

    begin 

    SELECT * INTO qtd FROM (SELECT DISTINCT cod_subject,COUNT(cod_classroom) AS CountOf FROM registration_subject 
    GROUP BY cod_subject HAVING COUNT(cod_classroom) = 4) AS total; 

    if found then 

    raise notice 'This subject has already 4 classroom'; 

    return null; 

    end if; 

    end;$BODY$ 
     LANGUAGE plpgsql VOLATILE 
     COST 100; 
    ALTER FUNCTION qtd() 
     OWNER TO postgres; 
+0

沒有添加適當的'LOCK'語句,這個函數很容易出現競爭條件,這意味着它會錯誤地拒絕併發刪除操作中的合法更改,並且會錯誤地允許多次插入。你*必須*鎖定'registration_subject'表'IN EXCLUSIVE MODE'以獲得可靠的結果。考慮'SELECT ... FOR SHARE'行鎖不足以防止併發插入。 –

回答

0

除了問題克雷格提到在他的評論(需要鎖定在獨佔模式下) ,我認爲你還有其他一些問題。

您的查詢是這樣的,它對我沒有多大意義。

SELECT * INTO qtd 
    FROM (SELECT DISTINCT cod_subject,COUNT(cod_classroom) AS CountOf 
      FROM registration_subject 
GROUP BY cod_subject HAVING COUNT(cod_classroom) = 4) AS total; 

我不相信這是一個非常有用的方法來做這個查詢。事實上,一旦任何科目有4個教室,它都會有利地拒絕所有插頁。

我建議改爲:

PERFORM count(cod_classroom) 
     FROM registration_subject 
     WHERE cod_subject = NEW.subject 
    HAVING count(*) >= 4; 

PERFORM在PLPGSQL使用,當你不關心使用的結果。這裏你只關心它是否被發現。其次,如果出現錯誤並且允許插入雜散,您仍然會阻止後續插入。如果任何主題有四個教室,但您的舊代碼將阻止插入所有主題,但5個教室沒問題,這不是您想要的。