1

我试图以某种方式在删除表时触发自动功能删除,但我不知道该怎么做。

TL;DR:有没有办法在删除特定表时触发函数删除?(POSTGRESQL 11.7)


详细解释

我将尝试使用带有虚拟名称的简化用例来解释我的问题。

  1. 我有三个表:sensor1、sensor2sumSensors

  2. 创建了一个FUNCTION ( sumdata ) 以在sumSensors上插入数据。在这个函数中,我将从sensor1sensor2表中获取数据并将其总和插入到表 sumSensors 中;

  3. 为每个传感器表创建了一个触发器,如下所示:

    为每一行执行函数 sumdata(); 在传感器 1 上插入后创建触发器 trig1

  4. 现在,当在表sensor1sensor2上插入新行时,将执行函数sumdata并在表 sumSensors 上插入两者的最后一个值的总和

如果我愿意DROP FUNTION sumdata CASCADE;,触发器将自动从表sensor1sensor2中删除。到现在为止一切都很好!但这不是我想要的。


我的问题是:

问:如果我只是DROP TABLE sumSensors CASCADE;?打算在此表上插入的函数会发生什么情况?

A:正如所料,由于 sumSensors 表和 sumdata 函数之间没有关联,所以函数不会被删除(仍然存在)!使用它的触发器也会发生同样的情况(仍然存在)。这意味着当在传感器表上插入新行时,函数 sumdata 将被执行并损坏,从而导致失败(即使是触发函数执行的 INSERT 也不会实际插入)。

有没有办法在删除特定表时触发函数删除?

先感谢您

4

1 回答 1

2

PostgreSQL 中的函数没有依赖跟踪(从版本 12 开始)。

您可以使用事件触发器来自己维护依赖关系。

完整示例如下。

更多信息:事件触发器特性支持函数的文档。

BEGIN;

CREATE TABLE _testtable ( id serial primary key, payload text );

INSERT INTO _testtable (payload) VALUES ('Test data');

CREATE FUNCTION _testfunc(integer) RETURNS integer
LANGUAGE SQL AS $$ SELECT $1 + count(*)::integer FROM _testtable; $$;

SELECT _testfunc(100);

CREATE FUNCTION trg_drop_dependent_functions()
RETURNS event_trigger 
LANGUAGE plpgsql AS $$
DECLARE
    _dropped record;
BEGIN
    FOR _dropped IN
        SELECT schema_name, object_name
        FROM pg_catalog.pg_event_trigger_dropped_objects()
        WHERE object_type = 'table'
    LOOP
        IF _dropped.schema_name = 'public' AND _dropped.object_name = '_testtable' THEN
            EXECUTE 'DROP FUNCTION IF EXISTS _testfunc(integer)';
        END IF;
    END LOOP;
END;
$$;

CREATE EVENT TRIGGER trg_drop_dependent_functions ON sql_drop
EXECUTE FUNCTION trg_drop_dependent_functions();

DROP TABLE _testtable;

ROLLBACK;
于 2020-04-16T00:04:13.730 回答