क्वास्नोई सही है; एक ट्रिगर यह हासिल करने का सबसे अच्छा तरीका होगा।
CREATE OR REPLACE FUNCTION enforce_photo_count() RETURNS trigger AS $$
DECLARE
max_photo_count INTEGER := 10;
photo_count INTEGER := 0;
must_check BOOLEAN := false;
BEGIN
IF TG_OP = 'INSERT' THEN
must_check := true;
END IF;
IF TG_OP = 'UPDATE' THEN
IF (NEW.owner != OLD.owner) THEN
must_check := true;
END IF;
END IF;
IF must_check THEN
-- prevent concurrent inserts from multiple transactions
LOCK TABLE photos IN EXCLUSIVE MODE;
SELECT INTO photo_count COUNT(*)
FROM photos
WHERE owner = NEW.owner;
IF photo_count >= max_photo_count THEN
RAISE EXCEPTION 'Cannot insert more than % photos for each user.', max_photo_count;
END IF;
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER enforce_photo_count
BEFORE INSERT OR UPDATE ON photos
FOR EACH ROW EXECUTE PROCEDURE enforce_photo_count();
मैं मेज शामिल आदेश स्थितियों में, जहां दो समवर्ती tansactions एक उपयोगकर्ता के लिए फ़ोटो में गिना जाएगा से बचने के लिए, देखना है कि मौजूदा संख्या सीमा से नीचे 1 है, में ताला लगा और फिर दोनों डालने:
कोड यह , जो आपको सीमा से 1 पर जाने का कारण बनता है। यदि यह आपके लिए चिंता नहीं है तो लॉकिंग को हटाना सबसे अच्छा होगा क्योंकि यह कई आवेषण/अपडेट के साथ बाधा बन सकता है।
स्रोत
2009-11-16 17:46:26
एक और बात: दुर्भाग्यवश, ट्रिगर की शुरुआत में सभी IF स्टेटमेंट्स को "IF TG_OP = 'INSERT' या (TG_OP = 'UPDATE' और NEW.owner! = OLD.owner) में शामिल नहीं किया जा सकता है फिर THEN ... "क्योंकि पीएलपीजीएसक्यूएल शॉर्ट सर्किटिंग का समर्थन नहीं करता है। –