Let's say we have a table BASE in a HANA:
CREATE COLUMN TABLE BASE
("CLIENT" NVARCHAR(3) DEFAULT '000' NOT NULL ,
"KEY" DECIMAL(21,7) CS_FIXED DEFAULT 0 NOT NULL ,
"VALUE_FIELD" NVARCHAR(100) DEFAULT '' NOT NULL,
CONSTRAINT "BASE~0" PRIMARY KEY ("CLIENT", "KEY"));
Then we create a log table to capture keys of changed records from the BASE table:
CREATE COLUMN TABLE LOG_TABLE
("CLIENT" NVARCHAR(3) DEFAULT '000' NOT NULL ,
"KEY" DECIMAL(21,7) CS_FIXED DEFAULT 0 NOT NULL ,
"LOG_TIMESTAMP" DECIMAL(21,7) CS_FIXED DEFAULT 0 NOT NULL ,
"DB_OPERATION" NVARCHAR(1) DEFAULT '' NOT NULL,
CONSTRAINT "LOG_TABLE~0" PRIMARY KEY ("CLIENT", "KEY", "LOG_TIMESTAMP"));
Here we don't care about value fields, only about keys. I have a trigger code generator depending on the necessity to log changes in specific clients or in all clients. For now, i came up with this solution:
CREATE OR REPLACE TRIGGER "trg_BASE_D"
AFTER DELETE ON "BASE"
REFERENCING OLD ROW AS R
FOR EACH ROW
BEGIN
INSERT INTO "LOG_TABLE" (CLIENT, KEY, LOG_TIMESTAMP, DB_OPERATION)
SELECT :R.CLIENT, :R.KEY, TO_NUMBER(TO_CHAR(CURRENT_UTCTIMESTAMP, 'YYYYMMDDHH24MISS.FF7')), 'D'
FROM DUMMY
WHERE :R.CLIENT IN ('010', '020');
END;
Of course, similar triggers are created for Insert and Update.
Question: does this solution of selecting from dummy
have any advantage over more explicit IF
solution? That is, do we have any performance implications when using dummy
and when using IF
?
For comparison:
CREATE OR REPLACE TRIGGER "trg_BASE_D_IF"
AFTER DELETE ON "BASE"
REFERENCING OLD ROW AS R
FOR EACH ROW
BEGIN
IF :R.CLIENT = '010' OR :R.CLIENT = '020' THEN
INSERT INTO "LOG_TABLE" (CLIENT, KEY, LOG_TIMESTAMP, DB_OPERATION)
VALUES (:R.CLIENT, :R.KEY, TO_NUMBER(TO_CHAR(CURRENT_UTCTIMESTAMP, 'YYYYMMDDHH24MISS.FF7')), 'D');
END IF;
END;
IF
automatically results in making SQL script sequential but, at the same time, it uses values directly, without using dummy
. Besides, there is nothing here to parallelise as the trigger is ROW-based; WHERE
solution doesn't use IF
but selects from dummy
. How will it impact the trigger performance? Or there will be no difference at all, and it comes down to personal preferences in this case? I prefer a WHERE
-based solution as it's easier to generate programmatically; however, both are quite easy to implement, so i'm open to either.
Sorry, i don't have access to an actual HANA DB to run performance tests - i only generate trigger code in ABAP...
If I had to guess I would assume that the procedural IF variant is better, as it does not need to prepare and execute a query - but the difference is likely small and probably smaller than other potential effects.
What I would rather worry about are bulk inserts into your table with many rows. There looping and performing a singular insert for each row might slow things down significantly. There I guess using the FOR EACH STATEMENT
variant with OLD TABLE
might be better as the insert in the log table can be done in bulk:
CREATE OR REPLACE TRIGGER "trg_BASE_D"
AFTER DELETE ON "BASE"
REFERENCING OLD TABLE AS R
FOR EACH STATEMENT
BEGIN
INSERT INTO "LOG_TABLE" (CLIENT, KEY, LOG_TIMESTAMP, DB_OPERATION)
SELECT CLIENT, KEY, TO_NUMBER(TO_CHAR(CURRENT_UTCTIMESTAMP, 'YYYYMMDDHH24MISS.FF7')), 'D'
FROM :R
WHERE CLIENT IN ('010', '020');
END;