【问题标题】:Track last modification timestamp of a row in Postgres跟踪 Postgres 中一行的最后修改时间戳
【发布时间】:2019-02-24 20:32:33
【问题描述】:

在 Postgres 中,我想存储表的最后更新/插入时间。 Microsoft SQL Server 提供了一个类型timestamp,它由数据库自动维护。

但 Postgres 中的 timestamp 工作方式不同,它不会自动更新,并且该列始终为空。

【问题讨论】:

  • 你需要一个在 Postgres 中的触发器
  • 如果你想在插入时记录它,只需像这样定义列:your_col TIMESTAMP DEFAULT NOW()。但是,如果没有上述触发器,它不会在更新时自动更改。

标签: postgresql timestamp


【解决方案1】:

在 postgresql 中,您必须使用触发器。您可以点击此链接了解如何操作https://x-team.com/blog/automatic-timestamps-with-postgresql/

要总结文章,您可以执行以下操作:

  1. 创建将被触发的Pl/Pgsql函数:

    CREATE OR REPLACE FUNCTION trigger_set_timestamp()
    RETURNS TRIGGER AS $$
    BEGIN
      NEW.updated_at = NOW();
      RETURN NEW;
    END;
    $$ LANGUAGE plpgsql;
    
  2. 创建你的表

    CREATE TABLE mytable (
      id SERIAL NOT NULL PRIMARY KEY,
      content TEXT,
      updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW()
    );
    
  3. 最后添加触发器:

    CREATE TRIGGER set_timestamp
    BEFORE UPDATE ON mytable
    FOR EACH ROW
    EXECUTE FUNCTION trigger_set_timestamp();
    

您可以在此处找到有关该问题的更多信息:https://dba.stackexchange.com/questions/58214/getting-last-modification-date-of-a-postgresql-database-table

希望对你有帮助。

【讨论】:

  • EXECUTE FUNCTION 需要替换为EXECUTE PROCEDURE
【解决方案2】:

扩展 SofienM 的出色答案(和 lolung 的评论更正),我们还可以通过自动更新具有行创建者的用户名(角色)的列,并使用 the 的用户名更新另一列来扩展它最后一个用户修改现有行。下面是您可以运行的完整测试(我使用两个假想用户(user1 和 user2)来演示测试):

--create dummy table, execute as user1
CREATE TABLE public.test_table (
  id SERIAL PRIMARY KEY,
  comments VARCHAR(250),
  create_by VARCHAR(250) DEFAULT user,
  create_dat TIMESTAMPTZ DEFAULT now(),
  modify_by VARCHAR(250) DEFAULT user,
  modify_dat TIMESTAMPTZ DEFAULT NOW()
);

--create function trigger to change a timestamp value upon an update
CREATE OR REPLACE FUNCTION trigger_set_timestamp()
RETURNS TRIGGER AS $$
BEGIN
  NEW.modify_dat = NOW();
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

--create a trigger to execute the function
CREATE TRIGGER set_timestamp
BEFORE UPDATE ON public.test_table
FOR EACH ROW
EXECUTE PROCEDURE trigger_set_timestamp();

--test the created by and created date columns, execute this as user1
INSERT INTO public.test_table (comments)
VALUES ('hello world'),
       ('hello system'),
       ('hello universe')
;

--wait a minute or two, execute this query as user1 and observe 'modify_dat' column
UPDATE public.test_table
SET comments = 'hello secret'
WHERE comments = 'hello world';

--create function trigger to change a username value upon an update
CREATE OR REPLACE FUNCTION trigger_set_usertimestamp()
RETURNS TRIGGER AS $$
BEGIN
  NEW.modify_by = user;
  RETURN NEW;
END;
$$ LANGUAGE plpgsql;

--create a trigger to execute the function
CREATE TRIGGER set_usertimestamp
BEFORE UPDATE ON public.test_table
FOR EACH ROW
EXECUTE PROCEDURE trigger_set_usertimestamp();

--test the created by and created date columns, execute this as user2 for variation
INSERT INTO public.test_table (comments)
VALUES ('goodbye world'),
       ('goodbye system'),
       ('goodbye universe')
;

--wait a minute or two, execute this query as user2 and observe 'modify_by' column
UPDATE public.test_table
SET comments = 'hello unknown'
WHERE comments = 'hello system';

改善这一点的方法是使触发器应用于给定架构中的任何/每个表,而不仅仅是一个特定的表(假设每个表当然都有“modify_dat”和“modify_by”列......)。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-05-28
    • 1970-01-01
    • 2023-03-08
    • 1970-01-01
    相关资源
    最近更新 更多