postgresql - 使用触发器和函数进行用户创建转储
问题描述
由于 PostgreSQL 不转储对象创建日期,所以我想通过使用触发器和函数手动转储用户创建日期。我已经创建了触发器和函数,但它不起作用。
CREATE TABLE user_audits (
usesysid INT GENERATED ALWAYS AS IDENTITY,
usename varchar NOT NULL,
created_on TIMESTAMP(6) NOT NULL
);
============================
CREATE OR REPLACE FUNCTION user_creation()
RETURNS TRIGGER
LANGUAGE PLPGSQL
AS
$$
BEGIN
IF NEW.usename <> OLD.usename THEN
INSERT INTO user_audits(usesysid,usename,created_on)
VALUES(usesysid,usename,now());
END IF;
RETURN NEW;
END;
$$
=================================
CREATE TRIGGER user_creation
BEFORE UPDATE
ON user
FOR EACH ROW
EXECUTE PROCEDURE user_creation();
这对于审计目的很重要,因为现在我使用日志文件来检查创建日期,但它会在一段时间后轮换。请建议将用户创建日期转储到表中的更好方法,以便我可以随时检索信息。谢谢
解决方案
我用下表创建了一个类似的练习:
- 该
user_tbl
表只有一个标识列usersysid
和username
CREATE TABLE user_tbl (
usersysid INT GENERATED ALWAYS AS IDENTITY,
username varchar NOT NULL
);
- 该
user_audits
表,您的稍作修改的版本:我在其中添加了一个id
身份字段。我从usersysid
字段中删除了身份(因为它将填充来自的身份user_tbl
)
CREATE TABLE user_audits (
id INT GENERATED ALWAYS AS IDENTITY,
usersysid INT,
username varchar NOT NULL,
created_on TIMESTAMP(6) NOT NULL
);
现在的函数,我检查是否OLD.username
为空,这意味着这是一个插入,如果NEW.username <> OLD.username
然后是一个更新。
CREATE OR REPLACE FUNCTION user_creation()
RETURNS TRIGGER
LANGUAGE PLPGSQL
AS
$$
BEGIN
IF OLD.username is null OR NEW.username <> OLD.username THEN
INSERT INTO user_audits(usersysid,username,created_on)
VALUES(NEW.usersysid,NEW.username,now());
END IF;
RETURN NEW;
END;
$$
;
最后是触发器,它同时在INSERT
或UPDATE
CREATE TRIGGER user_creation
BEFORE INSERT OR UPDATE
ON user_tbl
FOR EACH ROW
EXECUTE PROCEDURE user_creation();
现在,如果我创建两个新行并使用以下内容更新一个
insert into user_tbl (username) values('Carlo');
insert into user_tbl (username) values('Gianni');
update user_tbl set username='Giorgio' where usersysid=1;
我最终得到了user_tbl
包含 2 个预期的行
defaultdb=> select * from user_tbl;
usersysid | username
-----------+----------
2 | Gianni
1 | Giorgio
(2 rows)
和user_audits
包含 3 行的表(2 用于插入 + 1 用于更新)
defaultdb=> select * from user_audits;
id | usersysid | username | created_on
----+-----------+----------+----------------------------
1 | 1 | Carlo | 2021-06-04 13:57:44.810889
2 | 2 | Gianni | 2021-06-04 13:58:14.680878
3 | 1 | Giorgio | 2021-06-04 13:58:44.702364
(3 rows)
推荐阅读
- javascript - Javascript按钮删除整个表,应该只删除它创建的行
- android - 为什么每当我生成一个已签名的 APK 时都会收到重复输入错误?
- kotlin-multiplatform - 在 SQLDelight 中插入数据时没有这样的表
- sql - 根据查询中的日期删除行
- c++ - 如何将 vscode c++ stdout 重定向到调试输出?
- jquery - jquery DataTables 排序不正确
- wso2 - 如何使用 WSO2 SCIM 2.0 REST API 更新单个用户的组?
- html - 如何对齐 html 中的所有项目右边的元素?
- python - 如何更新函数之间的共享变量
- flutter - 从下拉菜单中获取选定的文本 (Flutter)