簡體   English   中英

模式中所有表的PL / PGSQL動態觸發器

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

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM