Frage

ich den Überblick über Änderungen der Datensätze in einer Tabelle zu halten haben. Was ich getan habe, ist eine zweite Tabelle erstellen, die erbt von den ersten und eine Revision Zähler addiert.

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

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

Dann habe ich einen Trigger, jedes Mal, Tabelle B A eingefügt / aktualisiert aktualisieren würde. Was ich kann nicht herausfinden, wie B.revision machen hält eine individuelle „Sequenz“ für jede ID.

. Beispiel: Tabelle A hat 2 Zeilen, i & j
i wurde bereits 3 mal aktualisiert und sollte drei Revisionen haben. (1, 2, 3)
j wurde bereits 2 mal aktualisiert und sollte zwei Revisionen haben: (1, 2)

.

Hier ist, was ich habe, so weit, vielleicht nach unten werde ich den falschen Weg und kann mir jemand helfen!

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();
War es hilfreich?

Lösung

Wenn Sie die Versionsnummern nur für die Bestellung, und nicht speziell brauchen sie eine ganze Zahl zu sein, dass Erhöhung um eins für jede Kennung, der einfachste Weg, es zu tun ist, eine Sequenz für die Revision zu verwenden und sie nur lassen tun, um die Tracking für Sie:

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();

Sie dann die verschiedenen Einsätze wie gewohnt:

    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)

So können Sie alle Überarbeitungen für eine bestimmte Zeile bekommen kann etwa so:

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

Andere Tipps

Hier ist mein Vorschlag:

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;

Ich habe die in eine coalesce „wenn nicht gefunden“, dass die „0“ wählen, wenn es keine bestehenden Revision ist. Dann habe ich in B legen Sie die Zeile, mit der inkrementierten Revision an.

Seien Sie vorsichtig mit Ihrem Erbe: Sie müssen das verwenden „nur“ keyword sich auf die A-Tabelle zu begrenzen, wenn die Auswahl und Aktualisierung, wie zum Beispiel:

select * from only A
update only A set foo = ... where id = ...

Dies ist ein Feature reiches Aduit Paket für Postgres, dass ich in der Vergangenheit verwendet habe: Audit-Trigger . Es verfolgt die Art der Aktualisierung (INSERT, UPDATE, DELETE) sowie die vor und nach den Werten für das Update.

--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
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top