有很多方法可以做到这一点,但如果你只是想让 PostgreSQL 确保你永远不会超额预订活动,你可以为你的桌子写INSERT
一个UPDATE
TRIGGER registration
。
我在我的 Supabase 实例上对此进行了测试,因为没有什么比从 StackOverflow 获得无效的专家答案更烦人的了!
CREATE TABLE person (id INTEGER UNIQUE PRIMARY KEY, firstname TEXT, lastname TEXT);
CREATE TABLE event (id INTEGER UNIQUE PRIMARY KEY, event_name TEXT, capacity INTEGER);
CREATE TABLE registration (id INTEGER UNIQUE PRIMARY KEY, event_id INTEGER , person_id INTEGER);
INSERT INTO person (id, firstname, lastname) VALUES (1, 'Bob','Barker'),(2, 'Jamie','Oliver'),(3, 'Gary ','Busey');
INSERT INTO event (id, event_name, capacity) VALUES (1, 'Fireman''s Ball', 2);
CREATE OR REPLACE FUNCTION check_registration_capacity()
RETURNS TRIGGER AS $$
BEGIN
IF (SELECT count(*) FROM registration as r1 WHERE r1.event_id = NEW.event_id) >
((SELECT capacity FROM event WHERE event.id = NEW.event_id) - 1)
THEN
RAISE EXCEPTION 'Event is full';
END IF;
RETURN NEW;
END;
$$ LANGUAGE plpgsql;
CREATE TRIGGER verify_registration_capacity
BEFORE INSERT OR UPDATE ON registration
FOR EACH ROW EXECUTE PROCEDURE check_registration_capacity();
-- register Bob for the Fireman's Ball
INSERT INTO registration (id, event_id, person_id) VALUES (1, 1, 1);
-- register Jamie for the Fireman's Ball
INSERT INTO registration (id, event_id, person_id) VALUES (2, 1, 2);
-- sorry, Gary, the next line throws an 'Event is full' error
INSERT INTO registration (id, event_id, person_id) VALUES (3, 1, 3);