See*_*die 8 postgresql trigger plpgsql functions row-modification-time
以前,我会将多个表合并为一个并返回结果,但在许多表中我有相同的列名。这就是为什么我决定用表名作为列名的前缀。但这打破了我必须自动更新我的updated_at专栏的触发器。
这是我的功能:
CREATE OR REPLACE FUNCTION update_updated_at()
RETURNS TRIGGER AS $$
BEGIN
NEW.updated_at = now();
RETURN NEW;
END;
$$ language 'plpgsql';
Run Code Online (Sandbox Code Playgroud)
我会添加一个触发器,如:
CREATE TRIGGER update_users_updated_at
BEFORE UPDATE ON users
FOR EACH ROW EXECUTE PROCEDURE update_updated_at();
Run Code Online (Sandbox Code Playgroud)
但是现在我的专栏被命名了users_updated_at,这不起作用。我的问题是有什么方法可以将列名传递给触发器并更新传递的列,还是有其他我不知道的方法?
使用spi 模块的moddatetime
moddatetime - 用于跟踪上次修改时间的函数
moddatetime() 是将当前时间存储到
timestamp字段中的触发器。这对于跟踪表中特定行的最后修改时间很有用。要使用,请使用此函数创建 BEFORE UPDATE 触发器。指定单个触发器参数:要修改的列的名称。该列的类型必须是时间戳或带时区的时间戳。
moddatetime.example 中有一个例子。
从上面引用的文件中,
DROP TABLE mdt;
CREATE TABLE mdt (
id int4,
idesc text,
moddate timestamp DEFAULT CURRENT_TIMESTAMP NOT NULL
);
CREATE TRIGGER mdt_moddatetime
BEFORE UPDATE ON mdt
FOR EACH ROW
EXECUTE PROCEDURE moddatetime (moddate);
INSERT INTO mdt VALUES (1, 'first');
INSERT INTO mdt VALUES (2, 'second');
INSERT INTO mdt VALUES (3, 'third');
SELECT * FROM mdt;
UPDATE mdt SET id = 4
WHERE id = 1;
UPDATE mdt SET id = 5
WHERE id = 2;
UPDATE mdt SET id = 6
WHERE id = 3;
SELECT * FROM mdt;
Run Code Online (Sandbox Code Playgroud)
所以这就是你需要的。
CREATE EXTENSION spi;
ALTER TABLE users ALTER timestamp_at SET DEFAULT now();
DROP TRIGGER IF EXISTS
update_users_updated_at ON users;
CREATE TRIGGER mdt_users
BEFORE UPDATE ON users
FOR EACH ROW
EXECUTE PROCEDURE moddatetime (timestamp_at);
Run Code Online (Sandbox Code Playgroud)