问题是,我的触发器(ON DELETE
)是在删除父记录之后执行的,并且在孙记录得到其触发器的执行时间之前,由于丢失了数据,我无法做任何有用的事情。
我有父表(tokens_processed
)
CREATE TABLE tokens_processed (
block_num INT PRIMARY KEY NOT NULL REFERENCES lock(block_num) ON DELETE CASCADE,
done boolean DEFAULT FALSE
);
2个子表(tokop
和approval
):
CREATE TABLE tokop (
tokop_id BIGSERIAL PRIMARY KEY,
block_num INT NOT NULL REFERENCES tokens_processed(block_num) ON DELETE CASCADE,
...
)
CREATE TABLE approval (
approval_id BIGSERIAL PRIMARY KEY,
block_num INT NOT NULL REFERENCES tokens_processed(block_num) ON DELETE CASCADE,
...
)
还有一个孙子表:
CREATE TABLE tokop_approval (
tokop_id BIGINT NOT NULL REFERENCES tokop(tokop_id) ON DELETE CASCADE,
approval_id BIGINT NOT NULL REFERENCES approval(approval_id) ON DELETE CASCADE
);
触发器的定义如下:
CREATE OR REPLACE FUNCTION tkapr_delete() RETURNS trigger AS $$
SELECT contract_id,from_id,to_id,value FROM tokop WHERE tokop_id=OLD.tokop_id INTO v_contract_id,v_from_id,v_to_id,v_value;
GET DIAGNOSTICS v_cnt = ROW_COUNT;
RAISE NOTICE 'contract_id=%, value=% tokop_id=%, v_cnt=%',v_contract_id,v_value,OLD.tokop_id,v_cnt;
...
END;
CREATE TRIGGER tkapr_insert AFTER INSERT ON tokop_approval FOR EACH ROW EXECUTE PROCEDURE tkapr_insert();
CREATE TRIGGER tkapr_delete BEFORE DELETE ON tokop_approval FOR EACH ROW EXECUTE PROCEDURE tkapr_delete();
当我从tokens_processed
删除记录时,触发器在tokop_approval
上执行,它表明父记录已被删除。但是我需要父母更新其他表中的某些字段。
通知输出证明了这一点:
NOTICE: contract_id=<NULL>, value=<NULL> tokop_id=131, v_cnt=0
如何在删除所有父记录(父及其子记录)之前执行触发器?因为现在执行触发器时,我缺少继续执行过程和更新其他表所需的数据。我创建外键约束(REFERENCES
)的原因是为了确保Postgres在删除父级之前不会调用我的触发器,但这只是做到了:(