Postgres-轨道更改

发布于 2025-02-07 11:37:46 字数 1818 浏览 2 评论 0原文

我想跟踪表中的历史记录更改,因为我创建了一个历史表,现在正在保存旧值和新值,但是我想从常规表中保存FK中的一列。

这是我的历史表:

CREATE TABLE IF NOT EXISTS sales.history (
    history_id integer PRIMARY KEY NOT NULL,
    mytable_id integer,
    table_name varchar(30),
    new_val json,
    old_val json,
    operation varchar(10),
    CONSTRAINT "fk sales.mytable_id to history.mytable_id" FOREIGN KEY (mytable_id) REFERENCES sales.sales (mytable_id)
) TABLESPACE pg_default;

我创建​​了一个跟踪更新,插入和删除

CREATE TRIGGER t_history BEFORE INSERT OR UPDATE OR DELETE ON sales.sales
 
        FOR EACH ROW EXECUTE PROCEDURE core.func_store_history_changes();

触发器

CREATE OR REPLACE FUNCTION core.func_store_history_changes() RETURNS trigger AS $$ 
        BEGIN 
                IF      TG_OP = 'INSERT'
                THEN
                        INSERT INTO sales.history (tabname, schemaname, operation, new_val)
                                VALUES (TG_RELNAME, TG_TABLE_SCHEMA, TG_OP, row_to_json(NEW));
                        RETURN NEW;
                ELSIF   TG_OP = 'UPDATE'
                THEN 
                        INSERT INTO sales.history (tabname, schemaname, operation, new_val, old_val)
 
                                VALUES (TG_RELNAME, TG_TABLE_SCHEMA, TG_OP,
 
                                        row_to_json(NEW), row_to_json(OLD));
                        RETURN NEW;
                ELSIF   TG_OP = 'DELETE'
                THEN
                        INSERT INTO sales.history (tabname, schemaname, operation, old_val)
                                VALUES (TG_RELNAME, TG_TABLE_SCHEMA, TG_OP, row_to_json(OLD));
                        RETURN OLD;
                END IF;
        END;
$$ LANGUAGE 'plpgsql' SECURITY DEFINER;

的 我的历史表?

问候

I want to track the history changes from my table, for that I created one history table, right now is saving old and new values, but I want to save in one column the fk from my regular table.

This is my history table:

CREATE TABLE IF NOT EXISTS sales.history (
    history_id integer PRIMARY KEY NOT NULL,
    mytable_id integer,
    table_name varchar(30),
    new_val json,
    old_val json,
    operation varchar(10),
    CONSTRAINT "fk sales.mytable_id to history.mytable_id" FOREIGN KEY (mytable_id) REFERENCES sales.sales (mytable_id)
) TABLESPACE pg_default;

I created a trigger to track update,insert and delete

CREATE TRIGGER t_history BEFORE INSERT OR UPDATE OR DELETE ON sales.sales
 
        FOR EACH ROW EXECUTE PROCEDURE core.func_store_history_changes();

Now my function

CREATE OR REPLACE FUNCTION core.func_store_history_changes() RETURNS trigger AS $ 
        BEGIN 
                IF      TG_OP = 'INSERT'
                THEN
                        INSERT INTO sales.history (tabname, schemaname, operation, new_val)
                                VALUES (TG_RELNAME, TG_TABLE_SCHEMA, TG_OP, row_to_json(NEW));
                        RETURN NEW;
                ELSIF   TG_OP = 'UPDATE'
                THEN 
                        INSERT INTO sales.history (tabname, schemaname, operation, new_val, old_val)
 
                                VALUES (TG_RELNAME, TG_TABLE_SCHEMA, TG_OP,
 
                                        row_to_json(NEW), row_to_json(OLD));
                        RETURN NEW;
                ELSIF   TG_OP = 'DELETE'
                THEN
                        INSERT INTO sales.history (tabname, schemaname, operation, old_val)
                                VALUES (TG_RELNAME, TG_TABLE_SCHEMA, TG_OP, row_to_json(OLD));
                        RETURN OLD;
                END IF;
        END;
$ LANGUAGE 'plpgsql' SECURITY DEFINER;

As you can see my history table has mytable_id which is a foreign key and primary key from sales table, how i can get that value and insert into my history table?

Regards

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

孤芳又自赏 2025-02-14 11:37:46

对于您的特定问题,我想您可以使用new.mytable_id 并在插入之后使用触发器 ...

以下是一个例子,我只写了第一个if(插入)。

CREATE TABLE IF NOT EXISTS sales.history (
    history_id serial PRIMARY KEY NOT NULL,
    mytable_id integer,
    table_name varchar(30),
    new_val json,
    old_val json,
    operation varchar(10),
    CONSTRAINT "fk sales.mytable_id to history.mytable_id" FOREIGN KEY (mytable_id) REFERENCES sales.sales (mytable_id)
) TABLESPACE pg_default;


CREATE TRIGGER t_history AFTER INSERT OR UPDATE OR DELETE ON sales.sales
 
        FOR EACH ROW EXECUTE PROCEDURE core.func_store_history_changes();


CREATE OR REPLACE FUNCTION core.func_store_history_changes() RETURNS trigger AS $ 
        BEGIN 
                IF      TG_OP = 'INSERT'
                THEN
                        INSERT INTO sales.history (table_name, operation,mytable_id, new_val)
                                VALUES (TG_RELNAME, TG_OP, NEW.mytable_id, row_to_json(NEW));
                        RETURN NEW;
                ELSIF   TG_OP = 'UPDATE'
                THEN 
                        INSERT INTO sales.history (tabname, schemaname, operation, new_val, old_val)
 
                                VALUES (TG_RELNAME, TG_TABLE_SCHEMA, TG_OP,
 
                                        row_to_json(NEW), row_to_json(OLD));
                        RETURN NEW;
                ELSIF   TG_OP = 'DELETE'
                THEN
                        INSERT INTO sales.history (tabname, schemaname, operation, old_val)
                                VALUES (TG_RELNAME, TG_TABLE_SCHEMA, TG_OP, row_to_json(OLD));
                        RETURN OLD;
                END IF;
        END;
$ LANGUAGE 'plpgsql' SECURITY DEFINER;

结果:

# insert into sales.sales (value) values ('2.3');
INSERT 0 1
# select * from sales.sales;
 mytable_id | value 
------------+-------          
          5 |  2.30
(2 rows)

# select * from sales.history;
 history_id | mytable_id | table_name |            new_val            | old_val | operation 
------------+------------+------------+-------------------------------+---------+-----------          
          3 |          5 | sales      | {"mytable_id":5,"value":2.30} |         | INSERT
(2 rows)

但是,也许您可​​以尝试为任何表使用此通用触发器。

https://github.com/2ndquadrant/audit-trigger

For you specific problem, I guess that you could use NEW.mytable_id and use trigger AFTER INSERT ...

Here is a example, I've wrote only the first if (INSERT).

CREATE TABLE IF NOT EXISTS sales.history (
    history_id serial PRIMARY KEY NOT NULL,
    mytable_id integer,
    table_name varchar(30),
    new_val json,
    old_val json,
    operation varchar(10),
    CONSTRAINT "fk sales.mytable_id to history.mytable_id" FOREIGN KEY (mytable_id) REFERENCES sales.sales (mytable_id)
) TABLESPACE pg_default;


CREATE TRIGGER t_history AFTER INSERT OR UPDATE OR DELETE ON sales.sales
 
        FOR EACH ROW EXECUTE PROCEDURE core.func_store_history_changes();


CREATE OR REPLACE FUNCTION core.func_store_history_changes() RETURNS trigger AS $ 
        BEGIN 
                IF      TG_OP = 'INSERT'
                THEN
                        INSERT INTO sales.history (table_name, operation,mytable_id, new_val)
                                VALUES (TG_RELNAME, TG_OP, NEW.mytable_id, row_to_json(NEW));
                        RETURN NEW;
                ELSIF   TG_OP = 'UPDATE'
                THEN 
                        INSERT INTO sales.history (tabname, schemaname, operation, new_val, old_val)
 
                                VALUES (TG_RELNAME, TG_TABLE_SCHEMA, TG_OP,
 
                                        row_to_json(NEW), row_to_json(OLD));
                        RETURN NEW;
                ELSIF   TG_OP = 'DELETE'
                THEN
                        INSERT INTO sales.history (tabname, schemaname, operation, old_val)
                                VALUES (TG_RELNAME, TG_TABLE_SCHEMA, TG_OP, row_to_json(OLD));
                        RETURN OLD;
                END IF;
        END;
$ LANGUAGE 'plpgsql' SECURITY DEFINER;

Result:

# insert into sales.sales (value) values ('2.3');
INSERT 0 1
# select * from sales.sales;
 mytable_id | value 
------------+-------          
          5 |  2.30
(2 rows)

# select * from sales.history;
 history_id | mytable_id | table_name |            new_val            | old_val | operation 
------------+------------+------------+-------------------------------+---------+-----------          
          3 |          5 | sales      | {"mytable_id":5,"value":2.30} |         | INSERT
(2 rows)

But, maybe, you could try to use this generic trigger for any table.

https://github.com/2ndQuadrant/audit-trigger

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文