在 POSTGRESQL 11.7 上 DROP TABLE 时自动 DROP FUNCTION
Automatically DROP FUNCTION when DROP TABLE on POSTGRESQL 11.7
我正在尝试以某种方式在删除 table 时触发自动函数删除,但我不知道该怎么做。
TL;DR:有没有办法在删除特定 table 时触发函数删除? (POSTGRESQL 11.7)
详细解释
我将尝试使用带有虚拟名称的简化用例来解释我的问题。
我有三个 table:sensor1、sensor2 和 sumSensors;
已创建 FUNCTION (sumdata) 以 INSERT 数据 sumSensors table。在这个函数中,我将从 sensor1 和 sensor2 tables 获取数据并将其总和插入 table sumSensors;
为每个传感器创建了一个触发器 table,如下所示:
创建触发器 trig1
插入传感器 1 后
对于每一行执行
函数 sumdata();
现在,当在 tables 上插入 新行时 sensor1 或 sensor2, 函数 sumdata 将被执行并且 插入 table sumSensors
上两个最后值的总和
如果我想 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;
我正在尝试以某种方式在删除 table 时触发自动函数删除,但我不知道该怎么做。
TL;DR:有没有办法在删除特定 table 时触发函数删除? (POSTGRESQL 11.7)
详细解释
我将尝试使用带有虚拟名称的简化用例来解释我的问题。
我有三个 table:sensor1、sensor2 和 sumSensors;
已创建 FUNCTION (sumdata) 以 INSERT 数据 sumSensors table。在这个函数中,我将从 sensor1 和 sensor2 tables 获取数据并将其总和插入 table sumSensors;
为每个传感器创建了一个触发器 table,如下所示:
创建触发器 trig1 插入传感器 1 后 对于每一行执行 函数 sumdata();
现在,当在 tables 上插入 新行时 sensor1 或 sensor2, 函数 sumdata 将被执行并且 插入 table sumSensors
上两个最后值的总和
如果我想 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;