我正在制作一个数据库,需要为学校系统存储数据,对于某些活动,未成年人需要许可证。 我有这个触发器,检查如果一个参与者是未成年人,那么他需要一个许可证。触发器行为奇怪
CREATE OR REPLACE FUNCTION absent_permit()
RETURNS trigger AS $body$
BEGIN
RAISE NOTICE 'ENTERS TRIGGER';
RAISE NOTICE 'AGE NEW PARTICIPANT = %', age_from_participant(NEW.id_part);
IF (age_from_participant(NEW.id_part) < 18) AND (NEW.permit IS NULL) THEN
RAISE NOTICE 'ENTERS IF';
RAISE NOTICE 'PARTICIPANT UNDER 18 NEED A PERMIT';
RAISE EXCEPTION 'MINOR WITHOUT PERMIT' USING HINT = 'PERMIT MUST BE != NULL';
RETURN NULL;
END IF;
RAISE NOTICE 'EXIT TRIGGER';
RETURN NEW;
END
$body$
LANGUAGE plpgsql;
CREATE TRIGGER check_permit BEFORE INSERT ON participant
FOR EACH ROW EXECUTE PROCEDURE absent_permit();
事实是:我第一次尝试插入一个小未经允许它不会因重复主键工作,反正插入,我第二次尝试给我一个错误相反,触发器工作并引发第一次应该提出的异常。函数age_from_participant确实以正确的方式工作,这不是问题。
有人可以告诉我我做错了什么吗?谢谢
编辑:添加表的人,插入
CREATE TABLE people (
fiscal_code varchar(16) PRIMARY KEY,
name varchar(20) NOT NULL,
surname varchar(20) NOT NULL,
phone numeric(10, 0) NOT NULL,
sex char(1) NOT NULL CHECK(sex IN ('M','F')),
email varchar(50) NOT NULL,
d_birth date NOT NULL
);
CREATE TABLE participant (
id_part varchar(10) PRIMARY KEY,
fiscal_code varchar(16) NOT NULL REFERENCES people(fiscal_code),
documents_code varchar(1000) NOT NULL,
section varchar(2) NOT NULL,
grade varchar(2) NOT NULL,
permit varchar(500),
school_code varchar(10) NOT NULL REFERENCES schools(school_code)
);
CREATE OR REPLACE FUNCTION age_from_participant(varchar)
RETURNS integer AS $$
DECLARE
alias_id_part ALIAS FOR $1;
precise_age interval;
BEGIN
SELECT AGE(CURRENT_DATE, d_birth) INTO precise_age FROM participant
JOIN PEOPLE USING(fiscal_code)
WHERE PARTICIPANT.ID_PART = alias_id_part;
RETURN date_part('year', precise_age)::INT;
END $$
LANGUAGE plpgsql;
INSERT INTO people VALUES ('RSSMRC', 'MARCO', 'ROSSI', 3490101123, 'M', '[email protected]', '2000-07-18');
INSERT INTO participant VALUES ('PART000001', 'RSSMRC','MR001','A','4',null, 'GEPC01000P');
的参与者,例如随着最后插入在第一时间将其插入它的权利,控制台提供:
NOTICE: ENTERS TRIGGER
NOTICE: AGE NEW PARTICIPANT =
NOTICE: EXIT TRIGGER
INSERT 0 1
Query returned successfully.
第二次,给出:
ERROR: MINOR WITHOUT PERMIT
HINT: PERMIT MUST BE != NULL
CONTEXT: PL/pgSQL function absent_permit() line 8 at RAISE
********** Error **********
ERROR: MINOR WITHOUT PERMIT
SQL state: P0001
Hint: PERMIT MUST BE != NULL
Context: PL/pgSQL function absent_permit() line 8 at RAISE
EDIT_2: 我解决了将鳕鱼触发器函数中的age_from_partecipant。还是不知道到底是什么没有工作,但这里是工作代码:
CREATE OR REPLACE FUNCTION absent_permit()
RETURNS trigger AS $body$
DECLARE
age interval;
BEGIN
SELECT AGE(CURRENT_DATE, D_birth) INTO age FROM participant JOIN people USING(fiscal_code) WHERE NEW.fiscal_code = people.fiscal_code;
RAISE NOTICE 'ENTERS TRIGGER';
RAISE NOTICE 'AGE NEW PARTICIPANT = %', date_part('year', age)::INT;
IF (date_part('year', age)::INT < 18) AND (NEW.permit IS NULL) THEN
RAISE NOTICE 'ENTERS IF';
RAISE NOTICE 'PARTICIPANT UNDER 18 NEED A PERMIT';
RAISE EXCEPTION 'MINOR WITHOUT PERMIT' USING HINT = 'PERMIT MUST BE != NULL';
RETURN NULL;
END IF;
RAISE NOTICE 'EXIT TRIGGER';
RETURN NEW;
END
$body$
LANGUAGE plpgsql;
CREATE TRIGGER check_permit BEFORE INSERT ON participant
FOR EACH ROW EXECUTE PROCEDURE absent_permit();
你应该用检查约束来做到这一点,而不是触发器。 –
我尝试过,但无法让它工作,所以我试着用触发器 – Trysme
你可以发布'età_from_participant'的定义吗?你能举一个实际显示行为的最小例子吗? (CREATE table ... CREATE function CREATE trigger ... INSERT INTO参与者...)? – joanolo