有没有办法从Postgres的所有表中删除所有触发器? 我知道有一个pg_trigger表,但看起来它不包含足够的信息让我解密我添加到表中的哪些触发器。此外,外键约束似乎也出现在pg_trigger表中,而我不想删除。我只想从我的表中删除用户创建的触发器并保留FK。
有什么建议吗?
有什么建议吗?
谢谢,James。
来自Drop ALL triggers from Postgres DB?的函数仅删除第一个表中的触发器,并保留其他表中具有相同名称的触发器。这是修复后的函数:
CREATE OR REPLACE FUNCTION strip_all_triggers() RETURNS text AS $$ DECLARE
triggNameRecord RECORD;
triggTableRecord RECORD;
BEGIN
FOR triggNameRecord IN select distinct(trigger_name) from information_schema.triggers where trigger_schema = 'public' LOOP
FOR triggTableRecord IN SELECT distinct(event_object_table) from information_schema.triggers where trigger_name = triggNameRecord.trigger_name LOOP
RAISE NOTICE 'Dropping trigger: % on table: %', triggNameRecord.trigger_name, triggTableRecord.event_object_table;
EXECUTE 'DROP TRIGGER ' || triggNameRecord.trigger_name || ' ON ' || triggTableRecord.event_object_table || ';';
END LOOP;
END LOOP;
RETURN 'done';
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;
select strip_all_triggers();
我更喜欢这个答案(基于这里)而不是被@kuznetso3v接受的答案,因为它让我有机会在复制粘贴之前检查DROP STATEMENT
:
SELECT 'DROP TRIGGER ' || trigger_name || ' ON ' || event_object_table || ';'
FROM information_schema.triggers
WHERE trigger_schema = 'public';
请在information_schema中查看:
SELECT * FROM information_schema.triggers;
只需级联删除您创建触发器的语言。
例如,我使用plpgsql
创建触发器,因此以下查询会立即删除所有触发器 -
DROP LANGUAGE plpgsql CASCADE;
更新:查看您需要的完整功能的真正解决方案。
好的,我想出了一个可以为我完成此操作的函数:
CREATE OR REPLACE FUNCTION strip_all_triggers() RETURNS text AS $$ DECLARE triggNameRecord RECORD; triggTableRecord RECORD; BEGIN FOR triggNameRecord IN select distinct(trigger_name) from information_schema.triggers where trigger_schema = 'public' LOOP SELECT distinct(event_object_table) INTO triggTableRecord from information_schema.triggers where trigger_name = triggNameRecord.trigger_name; RAISE NOTICE 'Dropping trigger: % on table: %', triggNameRecord.trigger_name, triggTableRecord.event_object_table; EXECUTE 'DROP TRIGGER ' || triggNameRecord.trigger_name || ' ON ' || triggTableRecord.event_object_table || ';'; END LOOP;
RETURN '完成'; END; $$ LANGUAGE plpgsql SECURITY DEFINER;
select strip_all_triggers();
这将删除公共模式中的任何触发器。
pg_dump -s
导出对象定义,并过滤以CREATE TRIGGER
开头的行。./pg_dump -s db_name | grep '^CREATE TRIGGER' | \
while read _ _ triggername _; do \
echo drop trigger "$triggername;"; \
done
alter table table_name disable trigger trigger_name
。我对旧答案的解决方案进行了两个改进:
CREATE OR REPLACE FUNCTION strip_all_triggers() RETURNS text AS $$ DECLARE
triggRecord RECORD;
BEGIN
create temp table all_triggers on commit drop as (
SELECT tgname AS trigger_name, n.nspname as trigger_schema, relname as trigger_table
FROM pg_trigger
JOIN pg_class ON pg_class.oid = tgrelid
JOIN pg_namespace n ON n.oid = pg_class.relnamespace);
FOR triggRecord IN select distinct on (trigger_schema, trigger_table, trigger_name) trigger_schema, trigger_table, trigger_name from all_triggers
where trigger_schema like 'public' and trigger_name like '%' -- MY FILTER
LOOP
RAISE NOTICE 'Dropping trigger: % on table: %.%', triggRecord.trigger_name, triggRecord.trigger_schema, triggRecord.trigger_table;
EXECUTE 'DROP TRIGGER ' || triggRecord.trigger_name || ' ON ' || triggRecord.trigger_schema || '.' || triggRecord.trigger_table || ';';
END LOOP;
RETURN 'done';
END
$$ LANGUAGE plpgsql SECURITY DEFINER;
select strip_all_triggers();
在 Drux 的回复之后(谢谢!),我添加了“distinct”关键字以消除破坏批量查询运行的重复语句。
SELECT distinct 'DROP TRIGGER ' || trigger_name || ' ON ' || event_object_table || ';'
FROM information_schema.triggers
WHERE trigger_schema = 'public';
你可以从这个查询开始,以找到触发器的名称:
select * from pg_trigger t,pg_proc where
pg_proc.oid=t.tgfoid
最佳答案仍然有缺陷,因为没有必要使用两个循环。
可以通过以下方式完成:
CREATE PROCEDURE _DropTableTriggers()
AS
$$
DECLARE
_rec RECORD;
BEGIN
FOR _rec IN
SELECT DISTINCT event_object_table, trigger_name
FROM INFORMATION_SCHEMA.triggers
LOOP
EXECUTE 'DROP TRIGGER ' || _rec.trigger_name || ' ON ' || _rec.event_object_table || ';';
END LOOP;
END
$$ LANGUAGE plpgsql SECURITY DEFINER;
information_schema
缺少TRUNCATE触发器,因此请使用类似以下的语句:SELECT tgname AS trigger_name, relname AS event_object_table FROM pg_trigger INNER JOIN pg_class ON pg_class.oid = tgrelid
。 - Lloekiquote_ident(triggNameRecord.trigger_name)
和quote_ident(triggTableRecord.event_object_table)
替换任何同时也是Postgres关键字的字符串,以正确引用它们。 - Mark McElroy