我在x86_64-redhat-linux-gnu上使用PostgreSQL 8.1.23
我必须编写一个数据库来保留语言课程的座位,并且要求应该有一个触发器,它将检查lector,我们是否正在尝试写入新组,同时还有任何其他组。我有这样的表:
CREATE TABLE groups (
group_id serial PRIMARY KEY,
lang varchar(3) NOT NULL,
level varchar(3),
seats int4,
lector int4,
start time,
day varchar(3),
FOREIGN KEY (language) REFERENCES languages(lang) ON UPDATE CASCADE ON DELETE CASCADE,
FOREIGN KEY (lector) REFERENCES lectors(lector_id) ON UPDATE CASCADE ON DELETE SET NULL);
和这样的触发器:
CREATE FUNCTION if_available () RETURNS trigger AS '
DECLARE
r groups%rowtype;
c groups%rowtype;
BEGIN
FOR r IN SELECT * FROM groups WHERE r.lector=NEW.lector ORDER BY group_id LOOP
IF (r.start = NEW.start AND r.day = NEW.day) THEN
RAISE NOTICE ''Lector already has a group at this time!'';
c = NULL;
EXIT;
ELSE
c = NEW;
END IF;
END LOOP;
RETURN c;
END;
' LANGUAGE 'plpgsql';
CREATE TRIGGER if_available_t
BEFORE INSERT OR UPDATE ON grupy
FOR EACH ROW EXECUTE PROCEDURE if_available();
将新行插入表groups
后,例如:
INSERT groups (lang, level, seats, lector, start, day) values ('ger','A-2',12,2,'11:45','wed');
我收到这样的错误:
ERROR: null value in column "group_id" violates not-null constraint
没有这个触发器一切都OK。有人能帮助我如何让它发挥作用吗?
答案 0 :(得分:0)
最后,我已经解决了!在BEGIN
之后应该有c = NEW;
,因为当表groups
在开头为空时,FOR循环不会运行并返回NULL
。我还在FOR循环中更改了条件:...WHERE lector = NEW.lector...
。最后,我更改了IF (r.group_id <> NEW.group_id AND r.start = NEW.start AND r.day = NEW.day) THEN...
的IF条件,因为我还没想在一次特定更新之前运行此触发器。也许这会对某人有帮助:))