Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I use a PostgreSQL triggers to store changes (SQL statements and row changes)

Using PostgreSQL triggers, is it possible to record the changes that have happened to a table due to INSERT or UPDATE SQL statements and log them to a file for later execution.

This is only to be used temporally so just something quick and dirty would do.

like image 545
jDempster Avatar asked Aug 18 '09 18:08

jDempster


People also ask

How do I use triggers in PostgreSQL?

Syntax. CREATE TRIGGER trigger_name [BEFORE|AFTER|INSTEAD OF] event_name ON table_name [ -- Trigger logic goes here.... ]; Here, event_name could be INSERT, DELETE, UPDATE, and TRUNCATE database operation on the mentioned table table_name. You can optionally specify FOR EACH ROW after table name.

What is instead of trigger in PostgreSQL?

An INSTEAD OF trigger is a trigger that allows you to skip an INSERT , DELETE , or UPDATE statement to a table or a view and execute other statements defined in the trigger instead. The actual insert, delete, or update operation does not occur at all.

Are Postgres triggers transactional?

All PostgreSQL triggers execute in the same transaction as the transaction that has triggered them. Edit: You can also use LISTEN + NOTIFY to send a message from your trigger to a code that executes outside of the transaction. In that case, the message will only be delivered at the point of a successful commit.


2 Answers

example of an audit trigger from https://www.postgresql.org/docs/current/static/plpgsql-trigger.html

CREATE TABLE emp (     empname           text NOT NULL,     salary            integer );  CREATE TABLE emp_audit(     operation         char(1)   NOT NULL,     stamp             timestamp NOT NULL,     userid            text      NOT NULL,     empname           text      NOT NULL,     salary integer );  CREATE OR REPLACE FUNCTION process_emp_audit() RETURNS TRIGGER AS $emp_audit$     BEGIN         --         -- Create a row in emp_audit to reflect the operation performed on emp,         -- make use of the special variable TG_OP to work out the operation.         --         IF (TG_OP = 'DELETE') THEN             INSERT INTO emp_audit SELECT 'D', now(), user, OLD.*;             RETURN OLD;         ELSIF (TG_OP = 'UPDATE') THEN             INSERT INTO emp_audit SELECT 'U', now(), user, NEW.*;             RETURN NEW;         ELSIF (TG_OP = 'INSERT') THEN             INSERT INTO emp_audit SELECT 'I', now(), user, NEW.*;             RETURN NEW;         END IF;         RETURN NULL; -- result is ignored since this is an AFTER trigger     END; $emp_audit$ LANGUAGE plpgsql;  CREATE TRIGGER emp_audit AFTER INSERT OR UPDATE OR DELETE ON emp     FOR EACH ROW EXECUTE PROCEDURE process_emp_audit(); 
like image 68
nos Avatar answered Sep 25 '22 16:09

nos


Do you actually need the audit log of queries stored in a table? The easiest way to get a file with all the queries that have been executed is to use postgresql's built-in logging.

In your postgresql.conf (usually in the $PG_DATA dir), set the following options appropriately:

log_directory '/path/to/log/dir' log_filename = 'filename.log' log_statement = 'mod' 

That last option makes it log all the INSERT, UPDATE, DELETE, TRUNCATE, and COPY FROM statements.

More details in the Postgres docs: http://www.postgresql.org/docs/current/static/runtime-config-logging.html

like image 34
David Claridge Avatar answered Sep 25 '22 16:09

David Claridge