I want to make some detailed output when a trigger violation occurs. In the trigger below it should be some columns of obj
that should be logged.
So what will the best way to do it?, inserting into LOG_TABLE
does not work, because the transaction is rolled back in case of an exception.
CREATE OR REPLACE TRIGGER XYZ
NO CASCADE BEFORE UPDATE OF NAME ON MY_TABLE
REFERENCING NEW AS OBJ
FOR EACH ROW MODE DB2SQL
BEGIN
DECLARE ERROR_TEXT VARCHAR(1000);
IF
OBJ.NAME = ‘Z’
THEN
--Insert into MY_SCHEMA.LOG_TABLE(....);
SET ERROR_TEXT = 'Name not allowed';
SIGNAL SQLSTATE '7010101' SET MESSAGE_TEXT = ERROR_TEXT;
END IF;
END
You may use an autonomous procedure for that.
An autonomous procedure is a procedure that, when called, executes inside a new transaction independent of the original transaction. When the autonomous procedure successfully completes, it will commit the work performed within the procedure, but if it is unsuccessful, the procedure rolls back any work it performed. Whatever the result of the autonomic procedure, the transaction which called the autonomic procedure is unaffected. To specify a procedure as autonomous, specify the AUTONOMOUS keyword on the CREATE PROCEDURE statement.
Look at the example below.
Notes:
BLOB
and XML
.LOG_TABLE.OBJ
of BLOB
as well, if you don't like XML
data type in your log table.CREATE TABLE LOG_TABLE
(
ID INT NOT NULL GENERATED BY DEFAULT AS IDENTITY
, ERROR_TEXT VARCHAR(1000) NOT NULL
, TS TIMESTAMP NOT NULL DEFAULT CURRENT TIMESTAMP
, OBJ XML NOT NULL
)
CREATE TABLE MY_TABLE
(
ID INT NOT NULL GENERATED BY DEFAULT AS IDENTITY
, NAME VARCHAR(10) NOT NULL
)
CREATE OR REPLACE PROCEDURE LOG_TABLE
(
P_ERROR_TEXT VARCHAR(1000)
, P_OBJ BLOB(10K)
)
AUTONOMOUS
BEGIN
INSERT INTO LOG_TABLE (ERROR_TEXT, OBJ) VALUES (P_ERROR_TEXT, XMLPARSE(DOCUMENT P_OBJ));
END
CREATE OR REPLACE TRIGGER MY_TABLE_BUR
NO CASCADE BEFORE UPDATE OF NAME ON MY_TABLE
REFERENCING NEW AS OBJ
FOR EACH ROW MODE DB2SQL
BEGIN
DECLARE ERROR_TEXT VARCHAR(1000);
IF
OBJ.NAME = 'Z'
THEN
--Insert into MY_SCHEMA.LOG_TABLE(....);
CALL LOG_TABLE('Name not allowed: ' || OBJ.NAME, XMLSERIALIZE(XMLROW(OBJ.ID AS "ID", OBJ.NAME AS "NAME") AS BLOB(10K)));
SET ERROR_TEXT = 'Name not allowed';
SIGNAL SQLSTATE '70001' SET MESSAGE_TEXT = ERROR_TEXT;
END IF;
END
INSERT INTO MY_TABLE(NAME) VALUES ('X')
UPDATE MY_TABLE SET NAME = 'Z'
[IBM][CLI Driver][DB2/LINUXX8664] SQL0438N Application raised error or warning with diagnostic text: "Name not allowed". SQLSTATE=70001 SQLCODE=-438
SELECT * FROM MY_TABLE
ID | NAME |
---|---|
1 | X |
SELECT * FROM LOG_TABLE
ID | ERROR_TEXT | TS | OBJ |
---|---|---|---|
1 | Name not allowed: Z | 2024-12-11 07:51:02.850763 | <?xml version="1.0" encoding="UTF-8" ?><row><ID>1</ID><NAME>Z</NAME></row> |