在postgresql中跟踪修订

vei*_*lig 5 postgresql triggers plpgsql sql-function revisions

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

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

CREATE TABLE B (
revision INTEGER NOT NULL) INHERITS (A);
Run Code Online (Sandbox Code Playgroud)

然后我创建了一个触发器,每次插入/更新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();
Run Code Online (Sandbox Code Playgroud)

the*_*ory 8

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

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();
Run Code Online (Sandbox Code Playgroud)

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

    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)
Run Code Online (Sandbox Code Playgroud)

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

    try=# select * from b where id = 1 order by revision;
     id | foo | revision 
    ----+-----+----------
      1 | you |        1
      1 | you |        3
    (2 rows)
Run Code Online (Sandbox Code Playgroud)

  • 好吧,你可以在PostgreSQL 8.4上使用一个窗口函数来获得修订作为数字序列:`select*,rank()over(按照修订的id顺序分区)作为b的版本,其中id = 1;`. (3认同)