Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Postgresql 在实际发生任何删除之前执行触发器_Postgresql - Fatal编程技术网

Postgresql 在实际发生任何删除之前执行触发器

Postgresql 在实际发生任何删除之前执行触发器,postgresql,Postgresql,问题是,我的触发器(ON DELETE)是在父记录被删除后执行的,当孙子记录执行触发器时,我无法执行任何有用的操作,因为我丢失了数据 我有父表(tokens\u已处理) 2个子表(tokop和approval): 还有一张孙子桌: CREATE TABLE tokop_approval ( tokop_id BIGINT NOT NULL REFERENCES tokop(tokop_id) ON DELETE CASCADE, appro

问题是,我的触发器(
ON DELETE
)是在父记录被删除后执行的,当孙子记录执行触发器时,我无法执行任何有用的操作,因为我丢失了数据

我有父表(
tokens\u已处理

2个子表(
tokop
approval
):

还有一张孙子桌:

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\u processed
中删除记录时,触发器在
tokop\u approval
上执行,它显示父记录已被删除。但是,我需要父级更新其他表中的一些字段

请注意,输出证明了这一点:

NOTICE:  contract_id=<NULL>, value=<NULL> tokop_id=131, v_cnt=0
注意:合同id=,价值=tokop\u id=131,价值=0

如何在删除所有父记录(父记录及其子记录)之前执行触发器?因为,现在,当执行触发器时,我丢失了继续进程和更新其他一些表所需的数据。我创建外键约束(引用)的原因是为了确保Postgres在删除父项之前不会调用我的触发器,但它只是:(

在删除
tokop
表上的
触发器之前,您不能将与
tokop
表相关且需要访问该表的逻辑移动到
中吗?如果该逻辑取决于
tokop\u批准的存在,则触发器可以查询该逻辑。@Romankonova,不可以。因为granchild记录链接了两个表,并且当eleted,对我来说,它有一个含义,
取消链接
事件发生。这个事件在触发时,必须收集父记录的信息,以构建一个有意义的对象,而不仅仅是
ID
。我不明白的是,为什么postgres在启用级联的情况下,在删除过程中使数据库处于不一致的状态。它首先应该删除孙辈记录,然后是父辈记录,然后是祖辈记录,我认为它应该遵循层次结构,从底部开始删除。但它是以相反的顺序进行的。当你遍历一棵树时,你必须先删除叶子,然后才开始删除中间节点,但Postgres不能以这种方式工作
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();
NOTICE:  contract_id=<NULL>, value=<NULL> tokop_id=131, v_cnt=0