[英]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.