【问题标题】:Automatically DROP FUNCTION when DROP TABLE on POSTGRESQL 11.7在 POSTGRESQL 11.7 上 DROP TABLE 时自动 DROP FUNCTION
【发布时间】:2020-04-15 21:56:09
【问题描述】:

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

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


详细解释

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

  1. 我有三个表:sensor1、sensor2sumSensors

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

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

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

  4. 现在,当在表 sensor1 OR sensor2插入新行时,函数sumdata 将被执行并将两个表 sumSensors 中最后一个值的总和插入

    李>

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


我的问题是:

问:如果我只是 DROP TABLE sumSensors CASCADE;?本来要插入此表的函数会发生什么情况?

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

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

提前谢谢你

【问题讨论】:

    标签: postgresql function triggers drop


    【解决方案1】:

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

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

    完整示例如下。

    更多信息:documentation of event triggers featuresupport 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 $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;
    

    【讨论】:

    • 太棒了,解决了我的问题。非常感谢@filiprem,说实话!
    猜你喜欢
    • 2012-05-06
    • 2018-04-24
    • 1970-01-01
    • 2011-02-08
    • 2015-11-12
    • 2011-10-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多