我在 postgres 中创建了这两个表,
CREATE TABLE EMPLOYEE(
ID INT PRIMARY KEY NOT NULL,
NAME VARCHAR(100) NOT NULL,
ADDRESS VARCHAR (250) NOT NULL
);
CREATE TABLE HIST_EMPLOYEE(
HISTORYNUM INT NOT NULL,
ID INT NOT NULL,
NAME VARCHAR(100) NOT NULL,
ADDRESS VARCHAR (250) NOT NULL
);
Run Code Online (Sandbox Code Playgroud)
..所以每当我想插入、更新或删除EMPLOYEE表中的记录时,该记录都应该插入HIST_EMPLOYEE表中。无论是单行还是多行
..我知道这个网站上有很多答案..但问题是我在我的历史表中添加了一列HIST_EMPLOYEE..这就是为什么我不能使用大多数答案发布的这个脚本,
insert into hist_employee select * from employee
Run Code Online (Sandbox Code Playgroud)
...这是我到目前为止所开始的,但它有很多错误..
扳机
CREATE TRIGGER insertHistory
AFTER INSERT OR UPDATE ON employee --MAIN TABLE
EXECUTE PROCEDURE insertHistory('hist_employee'); --HISTORY TABLE
Run Code Online (Sandbox Code Playgroud)
触发功能
CREATE OR REPLACE FUNCTION insertHistory() RETURNS TRIGGER AS
$func$
BEGIN
EXECUTE format('insert into %I select * from %I', TG_ARGV[0] ,TG_TABLE_NAME );
return null;
END;
$func$
LANGUAGE plpgsql;
Run Code Online (Sandbox Code Playgroud)
笔记:
- 该触发器也应该适用或足够灵活,可以在具有不同列集的其他表上实现。
HISTORYNUM 列每个 id 都是唯一的,
并且,是否可以将这 3 个(插入后、更新后、删除前)合并到一个触发器中?
感谢所有回复的人...如果您发现我的问题太模糊,我很抱歉
我认为该列historynum使用起来太麻烦。我建议用时间戳替换它。您还可以添加指示操作类型的列。
create table employee (
id int primary key,
name text not null,
address text not null);
create table employee_history (
id int,
name text not null,
address text not null,
modified_at timestamp,
operation text);
Run Code Online (Sandbox Code Playgroud)
您必须先使用触发器才能访问当前修改/删除的行。
create or replace function trigger_on_employee()
returns trigger language plpgsql
as $function$
begin
if tg_op = 'DELETE' then
insert into employee_history
select old.*, current_timestamp, tg_op;
return old;
else
insert into employee_history
select new.*, current_timestamp, tg_op;
return new;
end if;
end; $function$;
create trigger trigger_on_employee
before insert or update or delete
on employee
for each row
execute procedure trigger_on_employee();
Run Code Online (Sandbox Code Playgroud)
一些测试:
insert into employee values
(1, 'John', 'Berlin'),
(2, 'Adam', 'Paris'),
(3, 'Mike', 'London');
update employee
set name = 'Anna'
where id = 1;
delete from employee
where id = 2;
select *
from employee_history
order by modified_at;
id | name | address | modified_at | operation
----+------+---------+----------------------------+-----------
1 | John | Berlin | 2015-12-20 16:26:35.703232 | INSERT
2 | Adam | Paris | 2015-12-20 16:26:35.703232 | INSERT
3 | Mike | London | 2015-12-20 16:26:35.703232 | INSERT
1 | Anna | Berlin | 2015-12-20 16:26:35.750609 | UPDATE
2 | Adam | Paris | 2015-12-20 16:26:35.761521 | DELETE
(5 rows)
Run Code Online (Sandbox Code Playgroud)
HISTORYNUM柱子?BEFORE 。 AFTER不过,您可以声明多个调用同一函数的触发器。这样一来,您所编写的触发器函数几乎肯定会遇到“变异表”错误。此外,每次发生更新时,您似乎都试图将“当前”表的全部内容复制到“历史”表中。您已经在伪记录和中分别拥有新数据( for和)和旧数据( for和) 。为什么不利用它呢?INSERTUPDATEUPDATEDELETENEWOLD
除此之外,你说你有
这么多错误..
也许如果您告诉我们其中一些问题,我们可以帮助您解决这些问题。
| 归档时间: |
|
| 查看次数: |
6332 次 |
| 最近记录: |