在 POSTGRESQL 11.7 上 DROP TABLE 时自动 DROP FUNCTION

Automatically DROP FUNCTION when DROP TABLE on POSTGRESQL 11.7

我正在尝试以某种方式在删除 table 时触发自动函数删除,但我不知道该怎么做。

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


详细解释

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

  1. 我有三个 table:sensor1、sensor2sumSensors;

  2. 已创建 FUNCTION (sumdata) 以 INSERT 数据 sumSensors table。在这个函数中,我将从 sensor1sensor2 tables 获取数据并将其总和插入 table sumSensors;

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

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

  4. 现在,当在 tables 上插入 新行时 sensor1sensor2, 函数 sumdata 将被执行并且 插入 table sumSensors

  5. 上两个最后值的总和

如果我想 DROP FUNTION sumdata CASCADE;,触发器会自动从 tables sensor1 中删除,并且传感器 2。到现在为止一切都很好!但这不是我想要的。


我的问题是:

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

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

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

提前致谢

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

您可以使用event triggers 自行维护依赖项。

完整示例如下。

更多信息:documentation of event triggers feature, support functions.

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  + 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;