Quantcast
Channel: SCN: Message List
Viewing all articles
Browse latest Browse all 9193

DB Update Trigger: SQLScript

$
0
0

We're attempting to create a table trigger which hits on update and records all updated fields in a change log table.  We've successfully created a basic trigger which compares hard coded variable names from the new and old row inputs.  For a more dynamic solution, we'd like to loop through all columns in the updated table to record any changes. Once successful, this solution will be applied across many tables (with a large amount of columns) which necessitates the dynamic approach.

 

The trigger code can be found below and in the attached file. A few notes on it's current state:

 

- The trigger should watch for updates to table "Projects"

- All field updates should create a row in table "ChangeLog"

- SAP HANA table "TABLE_COLUMNS" is used to read the current table's column structure

- Receiving the error (marked in code below, Line 33):

    

Could not execute 'CREATE TRIGGER TEST_PROJECT_NAME_CHG AFTER UPDATE ON "Projects" ...'

SAP DBTech JDBC: [1287]: identifier must be declared: NEW_ROW

 

 

We've looked all over SCN and read through the SQLScript Reference guide, but cannot find a solution.  This feels close, so I'm hoping a SQLScript expert could help take this to the finish line.

 

* Note, this is for custom tables which are edited via a large XS application. Therefore, we've determined that using a trigger (if possible) is the best approach.

 

Code

 

CREATE TRIGGER TEST_PROJECT_CHG

AFTER UPDATE ON "Projects"

REFERENCING NEW ROW new_row, OLD ROW old_row   

FOR EACH ROW                                            

BEGIN

   /* Data declaraions */

   DECLARE v_group_id NVARCHAR(20);

   DECLARE v_group_seq_id INT := 0;

   DECLARE v_app_user_name NVARCHAR(20);

   DECLARE v_curr_timestamp TIMESTAMP; 

   DECLARE table_name NVARCHAR(200) := 'Projects';

   DECLARE tbl_columns NVARCHAR(256) ARRAY;

   DECLARE tbl_indexes NVARCHAR(16) ARRAY;

   DECLARE l_index INTEGER; 

   DECLARE l_count INTEGER;

   DECLARE lt_tbldef TABLE (COLUMN_NAME NVARCHAR(256), INDEX_TYPE VARCHAR(16));

   DECLARE v_column_name NVARCHAR(256);

   DECLARE new_val NVARCHAR(1000);

   DECLARE old_val NVARCHAR(1000);

 

 

   /* Get session information */

   SELECT top 1 current_connection,

     MAP(mt.application_user_name,'',user_name,mt.application_user_name),

  current_timestamp

  INTO v_group_id, v_app_user_name, v_curr_timestamp

  FROM m_service_threads as mt

  WHERE mt.connection_id = current_connection;

 

/* Determine the number of table columns to loop through  */

SELECT COUNT(*) INTO l_count FROM "TABLE_COLUMNS" WHERE "TABLE_NAME" = table_name;

 

 

FOR l_index IN 1 .. l_count DO

  SELECT "COLUMN_NAME" INTO v_column_name FROM "TABLE_COLUMNS" WHERE "TABLE_NAME" = table_name AND "POSITION" = l_index;

 

 

  /* ERROR! Attempting to access the column data based on the v_column_name variable.  */

  SELECT v_column_name INTO new_val FROM :new_row;

  SELECT v_column_name INTO old_val FROM :old_row;

 

 

  /* Update Change Log table where the new column value is different than the old value */

  IF :old_val <> :new_val THEN

  v_group_seq_id := :v_group_seq_id + 10;

  insert into "ChangeLog" (

  "trxId",

  "trxCntInd",

  "table",

  "mainKey",

  "fullKey",

  "operation",

  "changeDt",

  "userName",

  "fieldName",

  "newValue",

  "oldValue"

  ) VALUES (

  :v_group_id,

  :v_group_seq_id,

  :table_name,

  :new_row."id",

  :new_row."id",

  'U',

  :v_curr_timestamp,

  :v_app_user_name,

  :v_column_name,

  new_row[:v_column_name],

  old_row[:v_column_name]);

  END IF;

 

 

END FOR;

END;


Viewing all articles
Browse latest Browse all 9193

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>