我正在製作一個數據庫,需要爲學校系統存儲數據,對於某些活動,未成年人需要許可證。 我有這個觸發器,檢查如果一個參與者是未成年人,那麼他需要一個許可證。觸發器行爲奇怪
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