[英]PL/PGSQL dynamic trigger for all tables in schema
我希望自动更新每个表更新与updated_at列的自动更新。 我能够使用触发器为特定的表做这项工作。 但是我无法在任何地方找到的主要目标是创建一个动态抓取架构中所有表的函数,并创建相同的触发器并仅更改触发器引用的表名。 对于我的生活,我无法弄清楚。
我相信这不应该像我一样狡猾,因为我们的架构中的表将具有完全相同的列名'updated_at'。
我尝试过并考虑过的一个解决方案是将表模式转换为数组,并迭代遍历每次迭代调用/创建触发器。 但是我没有大量的psql经验,所以我发现自己谷歌搜索了几个小时来解决这个小问题。
SELECT ARRAY (
SELECT
table_name::text
FROM
information_schema.tables
WHERE table_schema = 'public') as tables;
我也尝试过:
DO $$
DECLARE
t text;
BEGIN
FOR t IN
SELECT table_name FROM information_schema.columns
WHERE column_name = 'updated_at'
LOOP
EXECUTE format('CREATE TRIGGER update_updatedAt
BEFORE UPDATE ON %I
FOR EACH ROW EXECUTE PROCEDURE updated_at()',
t);
END loop;
END;
$$ language 'plpgsql';
程序:
CREATE OR REPLACE FUNCTION updated_at()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = now();
RETURN NEW;
END;
$$ language 'plpgsql';
你的DO
块有效。 唯一的问题是我们不能为多个触发器使用相同的触发器名称。 因此,您可以为触发器名称添加table_name后缀/前缀。
DO $$
DECLARE
t text;
BEGIN
FOR t IN
SELECT table_name FROM information_schema.columns
WHERE column_name = 'updated_at'
LOOP
EXECUTE format('CREATE TRIGGER update_updatedAt_%I
BEFORE UPDATE ON %I
FOR EACH ROW EXECUTE PROCEDURE updated_at()',
t,t);
END loop;
END;
$$ language 'plpgsql';
此外,您可以添加一个检查,以查看information_schema.triggers
是否已存在触发器是安全的。
IF NOT EXISTS ( SELECT 1 from information_schema.triggers
where trigger_name = 'update_updatedat_'|| t)
THEN
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.