Using a system-period temporal table for tracking auditing information
An audit trail of the changes that are made to the system-period temporal table can be made more informative with the addition of one or more generated expression columns.
- when was data modified,
- who modified the data
- what SQL operation modified the data.
To track when data was modified, define the table as a system-period temporal table. To track who and what SQL statement modified the data, use a generated expression column. For more information about available generated expression columns, see CREATE TABLE.
In the following example, the POLICY_INFO table contains two extra columns. AUDIT_USER tracks who modified the data by using the SESSION_USER special register. AUDIT_OP tracks the SQL operation that modified the data by using the DATA CHANGE OPERATION.
CREATE TABLE policy_info
(policy_id CHAR(4) NOT NULL,
coverage INT NOT NULL,
audit_user VARCHAR(128) GENERATED ALWAYS AS (SESSION_USER),
audit_op CHAR(1) GENERATED ALWAYS AS (DATA CHANGE OPERATION),
sys_start TIMESTAMP(12) NOT NULL GENERATED ALWAYS AS ROW BEGIN,
sys_end TIMESTAMP(12) NOT NULL GENERATED ALWAYS AS ROW END,
ts_id TIMESTAMP(12) NOT NULL GENERATED ALWAYS AS TRANSACTION START ID,
PERIOD SYSTEM_TIME (sys_start, sys_end) );
CREATE TABLE hist_policy_info LIKE policy_info;
ALTER TABLE policy_info ADD VERSIONING USE HISTORY TABLE hist_policy_info
ON DELETE ADD EXTRA ROW;
Each row in the system temporal table and its corresponding history table tracks whether the row was changed by an insert, update, or delete operation and the name of the user that last modified the row.
ON DELETE ADD EXTRA ROW
If the ON DELETE ADD EXTRA ROW clause is specified on the ALTER TABLE ADD VERSIONING statement, an extra row is inserted into the history table when a row is deleted from a system-period temporal table. This additional row contains information about the delete operation itself.
The following example illustrates the value of ON DELETE ADD EXTRA ROW. This example shows a series of three transactions. In June of 2014, USER1 inserts a row into the POLICY_INFO table. Then, in January of 2015, USER2 updates the row. Finally, in August of 2015, USER3 deletes the row:
INSERT INTO policy_info (policy_id, coverage)
VALUES ('A123',12000);
UPDATE policy_info
SET coverage = 25000
WHERE policy_id = 'A123'
DELETE FROM policy_info
WHERE policy_id = ‘A123’
Without the ON DELETE ADD EXTRA ROW clause, this series of transactions would write only the following two entries to the history table. The first entry records the row as it was before USER2 made her update, and the second entry records the row as it was before USER3 did his delete. The delete operation records the row as it last existed in the temporal table. Without the ON DELETE ADD EXTRA ROW clause, there is no audit record of the delete operation itself.
POLICY_ID | COVERAGE | AUDIT_USER | AUDIT_OP | SYS_START | SYS_END | TS_ID |
---|---|---|---|---|---|---|
A123 | 12000 | USER1 | I | 2014-06-31-22.31.33.495925 | 2015-01-31-22.31.33.857632 | 2014-06-31-22.31.33.495925 |
A123 | 25000 | USER2 | U | 2015-01-31-22.31.33.857632 | 2015-08-31-22.31.33.634521 | 2015-01-31-22.31.33.857632 |
With the ON DELETE ADD EXTRA ROW clause added to the ADD VERSIONING statement, an extra row is written history table. Because the row-begin and row-end values are generated for the extra row, they are the same timestamp value. This timestamp also matches the row-end value of the first row inserted for the delete. In the following table, this additional row is shown:
POLICY_ID | COVERAGE | AUDIT_USER | AUDIT_OP | SYS_START | SYS_END | TS_ID |
---|---|---|---|---|---|---|
A123 | 12000 | USER1 | I | 2014-06-31-22.31.33.495925 | 2015-01-31-22.31.33.857632 | 2014-06-31-22.31.33.495925 |
A123 | 25000 | USER2 | U | 2015-01-31-22.31.33.857632 | 2015-08-31-22.31.33.634521 | 2015-01-31-22.31.33.857632 |
A123 | 25000 | USER3 | D | 2015-08-31-22.31.33.634521 | 2015-08-31-22.31.33.634521 | 2015-08-31-22.31.33.634521 |