Auditing database record changes in Oracle
Extends Database interview questions - triggers using Sybase database
Q. What are some of the considerations in auditing database table data?
A.
- Creating audit tables without any constraints to store record changes. Audit tables are heavily hit with inserts, hence needs to have fewer indices if at all required.
- Decide on what combination of triggers are required like Create, Update, or Delete in the CRUD operations.
- Create the triggers.
Here is an example for a given table shown below
CREATE TABLE bus_rule( id NUMBER(30) NOT NULL, code VARCHAR2(50) NOT NULL, rule_entry_id NUMBER(30) NOT NULL, name VARCHAR2(100) NOT NULL, effective date NULL, expires date NULL, created_by VARCHAR2(30) NOT NULL, created_date TIMESTAMP NOT NULL, updated_by VARCHAR2(30) NOT NULL, updated_date TIMESTAMP NOT NULL, CONSTRAINT bus_rule_pk PRIMARY KEY (id), CONSTRAINT fk_bus_rule_rule_entry_id FOREIGN KEY (rule_entry_id) REFERENCES bus_rule_entry(id) );
Step 1: Create a corresponding audit table to store historical data. Note that this table does not have any constraints as it is historical table. It adds a new column called "crud_operation" to tag if the data stored was due to Create, Update or Delete.
CREATE TABLE bus_rule_audit( id NUMBER(30) NOT NULL, code VARCHAR2(50) NOT NULL, rule_entry_id NUMBER(30) NOT NULL, name VARCHAR2(100) NOT NULL, effective date NULL, expires date NULL, created_by VARCHAR2(30) NOT NULL, created_date TIMESTAMP NOT NULL, updated_by VARCHAR2(30) NOT NULL, updated_date TIMESTAMP NOT NULL, crud_operation char(1) NOT NULL );
Step 2: Create triggers in Oracle
CREATE OR REPLACE TRIGGER bus_rule_trig AFTER INSERT OR UPDATE OR DELETE ON bus_rule REFERENCING OLD AS OLD NEW AS NEW FOR EACH ROW DECLARE crud_operation CHAR(1); BEGIN IF INSERTING THEN crud_operation := 'C'; ELSIF UPDATING THEN crud_operation := 'U'; ELSIF DELETING THEN crud_operation := 'D'; END IF; IF INSERTING OR UPDATING THEN INSERT INTO bus_rule_audit (ID,CODE,RULE_ENTRY_ID,NAME,EFFECTIVE,EXPIRES,CREATED_BY,CREATED_DATE,UPDATED_BY,UPDATED_DATE,CRUD_OPERATION) VALUES (:NEW.ID, :NEW.CODE,:NEW.RULE_ENTRY_ID,:NEW.NAME,:NEW.EFFECTIVE,:NEW.EXPIRES,:NEW.CREATED_BY,:NEW.CREATED_DATE,:NEW.UPDATED_BY,:NEW.UPDATED_DATE, crud_operation); ELSE INSERT INTO bus_rule_audit (ID,CODE,RULE_ENTRY_ID,NAME,EFFECTIVE,EXPIRES,CREATED_BY,CREATED_DATE,UPDATED_BY,UPDATED_DATE,CRUD_OPERATION) VALUES (:OLD.ID, :OLD.CODE,:OLD.RULE_ENTRY_ID,:OLD.NAME,:OLD.EFFECTIVE,:OLD.EXPIRES,:OLD.CREATED_BY,:OLD.CREATED_DATE,:OLD.UPDATED_BY,:OLD.UPDATED_DATE, crud_operation); END IF; END;
Now, if you perform any CUD operation table bus_rule the bus_rule_trig will fire to insert records into the audit table bus_rule_audit.
Q. Why do you need to be careful as to where you use triggers?
A. The main problems with triggers are
a) they are global - they apply no matter what the context of the table activity; and
b) they are candid; it's easy to forget they are there until they hurt you with unintended consequences.
You may also like:
0 Comments:
Post a Comment
Subscribe to Post Comments [Atom]
<< Home