5

我必须跟踪表中记录的修订。我所做的是创建第二个表,它继承自第一个表并添加一个修订计数器。

CREATE TABLE A (
id SERIAL,
foo TEXT,
PRIMARY KEY (id));

CREATE TABLE B (
revision INTEGER NOT NULL) INHERITS (A);

然后我创建了一个触发器,每次插入/更新 A 时都会更新表 B。我想不通的是如何让 B.revision 为每个 id 保留一个单独的“序列”。

示例:表 A 有 2 行,i & j。
我已经更新了 3 次,应该有 3 次修订:(1、2、3)。
j 已经更新了 2 次,应该有两个修订:(1, 2)。

这是我到目前为止所拥有的,也许我走错了路,有人可以帮助我!

CREATE OR REPLACE FUNCTION table_update() RETURNS TRIGGER AS $table_update$
    DECLARE
        last_revision INTEGER;
    BEGIN
        SELECT INTO last_revision MAX(revision) FROM B WHERE id = NEW.id;

        IF NOT FOUND THEN
            last_revision := 0;
        END IF;

        INSERT INTO B SELECT NEW.*;

        RETURN NEW;
    END;
$table_update$ LANGUAGE plpgsql;

CREATE TRIGGER table_update
AFTER INSERT OR UPDATE ON A
    FOR EACH ROW EXECUTE PROCEDURE table_update();
4

4 回答 4

11

如果您只需要版本号来订购,并且不需要它们是每个标识符加一的整数,那么最简单的方法是使用修订序列并让它进行跟踪为你:

CREATE TABLE A (
    id SERIAL,
    foo TEXT,
    PRIMARY KEY (id)
);

CREATE TABLE B ( revision SERIAL NOT NULL) INHERITS (A);

CREATE OR REPLACE FUNCTION table_update() RETURNS TRIGGER AS $table_update$
    BEGIN
        INSERT INTO B SELECT NEW.*;
        RETURN NEW;
    END;
$table_update$ LANGUAGE plpgsql;

CREATE TRIGGER table_update
AFTER INSERT OR UPDATE ON A
    FOR EACH ROW EXECUTE PROCEDURE table_update();

然后像往常一样进行插入:

    try=# insert into a (foo) values ('bar');
    INSERT 0 1
    try=# insert into a (foo) values ('bar');
    INSERT 0 1
    try=# update a set foo = 'you' where id = 1;
    UPDATE 2
    try=# select * from b;
     id | foo | revision 
    ----+-----+----------
      2 | bar |        2
      1 | you |        1
      1 | you |        3
    (3 rows)

因此,您可以获得给定行的所有修订,如下所示:

    try=# select * from b where id = 1 order by revision;
     id | foo | revision 
    ----+-----+----------
      1 | you |        1
      1 | you |        3
    (2 rows)
于 2010-02-13T23:25:20.187 回答
0

这是我的建议:

CREATE OR REPLACE FUNCTION table_update() RETURNS TRIGGER AS $table_update$
DECLARE
    last_revision INTEGER;
BEGIN
    SELECT INTO last_revision coalesce(MAX(revision), 0) FROM B WHERE id = NEW.id;

    INSERT INTO B SELECT NEW.*, last_revision + 1;

    RETURN NEW;
END;
$table_update$ LANGUAGE plpgsql;

我将“如果未找到”更改为合并,如果没有现有修订,它将选择“0”。然后,我在 B 行中插入带有递增修订的行。

注意继承:在选择和更新时,您需要使用“only”关键字将自己限制在 A 表中,如下所示:

select * from only A
update only A set foo = ... where id = ...
于 2010-02-13T23:21:03.207 回答
0

Here is a feature rich Aduit package for postgres that I've used in the past: Audit Trigger. It tracks the type of update (insert, update, delete) as well as the before and after values for the update.

于 2014-01-04T16:06:06.750 回答
-1
--THIS TABLE AUTOMATICALLY INCREMENT THE COLUMN VALUES USING TRIGGER
CREATE TABLE emp_table(
  emp_id int not null,
  emp_name varchar not null,
  emp_rollno int not null,
  primary key(emp_id)
);

--Now create table with three column and emp_id is primary key
--and emp_rollno both are automatically increment in trigger is fired
CREATE or REPLACE FUNCTION emp_fun() RETURNS TRIGGER AS $BODY$
--creating function emp_fun()
DECLARE
BEGIN
  IF(tg_op='INSERT') THEN
    NEW.emp_id=COALESCE((SELECT MAX(emp_id)+1 FROM emp_table), 1);
    NEW.emp_rollno=COALESCE((SELECT MAX(emp_rollno)+1 FROM emp_table), 1);
    --trigger is fired values is automatically increment
END IF;

IF tg_op='DELETE' THEN RETURN OLD; ELSE RETURN NEW; END IF;
END; $BODY$LANGUAGE PLPGSQL

CREATE TRIGGER emp_fun BEFORE INSERT ON
  emp_table FOR EACH ROW EXECUTE PROCEDURE emp_fun();

INSERT INTO emp_table(emp_name) VALUES('BBB');
--insert the value tanle emp_table
SELECT * FROM emp_table
-- Check the result
于 2012-05-10T05:24:22.967 回答