如何在PostgreSQL中自动更新时间戳

我希望代码能够自动更新时间戳时,一个新的行插入,因为我可以在MySQL中使用CURRENT_TIMESTAMP。

我将如何在PostgreSQL中实现这一点?

CREATE TABLE users (
id serial not null,
firstname varchar(100),
middlename varchar(100),
lastname varchar(100),
email varchar(200),
timestamp timestamp
)
229030 次浏览

您需要编写一个插入触发器,如果您希望在记录更改时更改它,则可能需要编写一个更新触发器。这篇文章解释得很好:

http://www.revsys.com/blog/2006/aug/04/automatically-updating-a-timestamp-column-in-postgresql/

CREATE OR REPLACE FUNCTION update_modified_column()
RETURNS TRIGGER AS $$
BEGIN
NEW.modified = now();
RETURN NEW;
END;
$$ language 'plpgsql';

像这样应用触发器:

CREATE TRIGGER update_customer_modtime BEFORE UPDATE ON customer FOR EACH ROW EXECUTE PROCEDURE  update_modified_column();

要在插入期间填充列,使用DEFAULT值:

CREATE TABLE users (
id serial not null,
firstname varchar(100),
middlename varchar(100),
lastname varchar(100),
email varchar(200),
timestamp timestamp default current_timestamp
)

注意,该列的值可以通过在INSERT语句中提供一个值显式地覆盖。如果你想防止这种情况发生,你确实需要触发

如果你需要在行更新时更新该列,你还需要一个触发器(如e。j。布伦南提到的)

注意,对列名使用保留字通常不是一个好主意。你应该找到一个不同于timestamp的名字

仅在值更改时更新时间戳

基于E.J的链接,并从该链接添加一个if语句(https://stackoverflow.com/a/3084254/1526023)

CREATE OR REPLACE FUNCTION update_modified_column()
RETURNS TRIGGER AS $$
BEGIN
IF row(NEW.*) IS DISTINCT FROM row(OLD.*) THEN
NEW.modified = now();
RETURN NEW;
ELSE
RETURN OLD;
END IF;
END;
$$ language 'plpgsql';

使用'now()'作为默认值自动生成时间戳。

为了在插入新行时自动更新PostgresSQL中的时间戳字段,你可以设置current_timestamp作为它的default值:

CREATE TABLE users (
id serial not null,
firstname varchar(100),
middlename varchar(100),
lastname varchar(100),
email varchar(200),
timestamp timestamp default current_timestamp
)

除此之外,你可能想要阻止任何人在未来更新这个字段,这可以通过创建一个更新触发器并应用它来完成:

CREATE OR REPLACE FUNCTION stop_change_on_timestamp()
RETURNS trigger AS
$BODY$
BEGIN
-- always reset the timestamp to the old value ("actual creation time")
NEW.timestamp := OLD.timestamp;
RETURN NEW;
END;
$BODY$
CREATE TRIGGER prevent_timestamp_changes
BEFORE UPDATE
ON users
FOR EACH ROW
EXECUTE PROCEDURE stop_change_on_timestamp();

更新和Liquibase YAML:

databaseChangeLog:
- changeSet:
id: CREATE FUNCTION set_now_to_timestamp
author: Konstantin Chvilyov
changes:
- sql:
sql: CREATE OR REPLACE FUNCTION set_now_to_timestamp() RETURNS TRIGGER LANGUAGE plpgsql AS 'BEGIN NEW.timestamp = NOW(); RETURN NEW; END;'


- changeSet:
id: CREATE TRIGGER update_users_set_now_to_timestamp
author: Konstantin Chvilyov
changes:
- sql:
sql: CREATE TRIGGER update_users_set_now_to_timestamp BEFORE UPDATE ON users FOR EACH ROW EXECUTE PROCEDURE set_now_to_timestamp();