Interesting! I was going to ask if such a thing existed, but I was pretty
much convinced they did not so I didn't ask.
Looks like with version 9.5 DB2 supports global variables:
"Global variables improve data sharing between SQL statements.
Version 9.5 introduces the concept of global variables, which are named
memory variables that you can access and modify through SQL statements.
Global variables enable you to share data between different SQL statements
running in the same session (or connection) without the need for application
logic to support this data transfer."
The reason I had wanted something like this is for applications where a
generic userid is used for an application to connect to a database, but a
specific userid is used by the user when using the application. This way I
think we can do something like this:
CREATE VARIABLE global.userid VARCHAR(20) DEFAULT NULL^
CREATE TABLE maint_log (
userid VARCHAR(20)
, field_name VARCHAR(40) NOT NULL
, old_value VARCHAR(255)
, new_value VARCHAR(255)
)^
CREATE TRIGGER TEST.NAME_LOG_T R
AFTER UPDATE OF name, city, state
ON TEST.TABLE1
REFERENCING OLD AS old NEW AS new
FOR EACH ROW
MODE DB2SQL
BEGIN ATOMIC
IF NOT old.name = new.name THEN
INSERT INTO maint_log (userid, field_name, old_value, new_value)
VALUES (global.userid, 'NAME', old.name, new.name);
END IF;
IF NOT old.city = new.city THEN
INSERT INTO maint_log (userid, field_name, old_value, new_value)
VALUES (global.userid, 'CITY', old.city, new.city);
END IF;
IF NOT old.state = new.state THEN
INSERT INTO maint_log (userid, field_name, old_value, new_value)
VALUES (global.userid, 'STATE', old.state, new.state);
END IF;
END^
And then in an application:
CONNECT ...
SET global.userid = 'JAUser';
UPDATE test.table1
SET name = 'Frank Swarbrick'
, state = 'CA'
WHERE name = 'Francis J Swarbrick';
And then
SELECT * FROM maint_log;
gives:
USERID FIELD_NAME OLD_VALUE
NEW_VALUE
-------------------- ----------------------------------------
--------------------- -------------------
JAUser NAME Francis J
Swarbrick Frank Swarbrick
JAUser STATE CO
CA
This would allow the application to connect to the database and immediately
set the 'global.userid' variable. Then later it could do updates to tables
that have triggers attached and the trigger could retrieve the global.userid
variable and insert it in to the maintenance log table.
This seems to work, and seems to be to be a decent idea. Any thoughts?
One thing about the trigger is, could there possibly be a way to make the IF
and INSERT statements more generic so that I don't have to add a new one for
each column that I want to do logging for?
Anyway, cool new feature in DB2!
Frank
much convinced they did not so I didn't ask.
Looks like with version 9.5 DB2 supports global variables:
"Global variables improve data sharing between SQL statements.
Version 9.5 introduces the concept of global variables, which are named
memory variables that you can access and modify through SQL statements.
Global variables enable you to share data between different SQL statements
running in the same session (or connection) without the need for application
logic to support this data transfer."
The reason I had wanted something like this is for applications where a
generic userid is used for an application to connect to a database, but a
specific userid is used by the user when using the application. This way I
think we can do something like this:
CREATE VARIABLE global.userid VARCHAR(20) DEFAULT NULL^
CREATE TABLE maint_log (
userid VARCHAR(20)
, field_name VARCHAR(40) NOT NULL
, old_value VARCHAR(255)
, new_value VARCHAR(255)
)^
CREATE TRIGGER TEST.NAME_LOG_T R
AFTER UPDATE OF name, city, state
ON TEST.TABLE1
REFERENCING OLD AS old NEW AS new
FOR EACH ROW
MODE DB2SQL
BEGIN ATOMIC
IF NOT old.name = new.name THEN
INSERT INTO maint_log (userid, field_name, old_value, new_value)
VALUES (global.userid, 'NAME', old.name, new.name);
END IF;
IF NOT old.city = new.city THEN
INSERT INTO maint_log (userid, field_name, old_value, new_value)
VALUES (global.userid, 'CITY', old.city, new.city);
END IF;
IF NOT old.state = new.state THEN
INSERT INTO maint_log (userid, field_name, old_value, new_value)
VALUES (global.userid, 'STATE', old.state, new.state);
END IF;
END^
And then in an application:
CONNECT ...
SET global.userid = 'JAUser';
UPDATE test.table1
SET name = 'Frank Swarbrick'
, state = 'CA'
WHERE name = 'Francis J Swarbrick';
And then
SELECT * FROM maint_log;
gives:
USERID FIELD_NAME OLD_VALUE
NEW_VALUE
-------------------- ----------------------------------------
--------------------- -------------------
JAUser NAME Francis J
Swarbrick Frank Swarbrick
JAUser STATE CO
CA
This would allow the application to connect to the database and immediately
set the 'global.userid' variable. Then later it could do updates to tables
that have triggers attached and the trigger could retrieve the global.userid
variable and insert it in to the maintenance log table.
This seems to work, and seems to be to be a decent idea. Any thoughts?
One thing about the trigger is, could there possibly be a way to make the IF
and INSERT statements more generic so that I don't have to add a new one for
each column that I want to do logging for?
Anyway, cool new feature in DB2!
Frank
Comment