logo

Are you need IT Support Engineer? Free Consultant

How to Track Data Changes in RAP and Change Log Me…

  • By Sanjay
  • 09/05/2026
  • 4 Views


hi, 

A change log table alone can be used to track data modifications without storing full historical snapshots. The main table contains the active business data, while the change log table records only the metadata of each change, such as the key fields of the affected record, change type (insert, update, delete), user, and optionally the reason for change.  

 During the RAP save sequence, determinations in the behavior implementation capture these details before the transaction is committed and insert them into the change log table. This approach provides a lightweight audit trail that allows you to track when and by whom changes were made, making it suitable for compliance monitoring, reporting, and troubleshooting, while avoiding the storage overhead of a shadow table that keeps the full data history. 

 

Here we see some major key Advantages. 

  • Lower Storage Requirements – Since it stores only metadata (keys, change type, timestamp, user, etc.) instead of full data snapshots, it uses significantly less database space than a shadow table. 
  • Better Performance – Writing smaller log entries reduces the impact on transaction performance compared to saving entire records. 
  • Simplified Design – Only one additional table is needed, making the data model and maintenance simpler. 
  • Faster Reporting on Changes – The log contains concise, relevant details, making it easier to query and generate audit reports. 
  • Regulatory Compliance – Still fulfills many compliance and audit requirements by showing who changed what and when. 

Steps to achieving  the Track Change Log Mechanism in RAP. 

I have create 2 database tables  

  1. For basic details 
  1. Capturing the changes record table 

Gireesh_Pg1_0-1757662408594.Png

 

Table 2.

 

Gireesh_Pg1_1-1757662442048.Png

 

Step2. 

We have to create root view  on top of the database table. 

 

Gireesh_Pg1_2-1757662471459.Png

And we have to create data definition for change log also. 

 

Gireesh_Pg1_3-1757662495876.Png

 

Step 3. 

for the basic data definition we have create on metadata extension for front end display. 

 

@Metadata.layer:#CORE 

annotate entity zgiri_i_empl_details 

with  

{ 

@UI.facet: [  

{  

id: 'object', 

label: 'Basic Data', 

type: #IDENTIFICATION_REFERENCE, 

purpose: #STANDARD, 

position: 10 }] 

@UI.lineItem: [{ label: 'Id' , position: 10 }] 

@UI.identification: [{ label: 'Id' , position: 10 }] 

Id; 

@UI.lineItem: [{ label: 'Name' , position: 20 }] 

@UI.identification: [{ label: 'Name' , position: 20 }] 

Name; 

@UI.lineItem: [{ label: 'Department' , position: 30 }] 

@UI.identification : [{ label: 'Department' , position: 30 }] 

Department; 

@UI.lineItem: [{ label: 'CurrKey' , position: 40 }] 

@UI.identification : [{ label: 'CurrKey' , position: 40 }] 

CurrKey; 

@UI.lineItem: [{ label: 'Salary' , position: 50 }] 

@UI.identification : [{ label: 'Salary' , position: 50 }] 

Salary; 

@UI.lineItem: [{ label: 'CreatedBy' , position: 60 }] 

CreatedBy; 

@UI.lineItem: [{ label: 'CreatedAt' , position: 70 }] 

CreatedAt; 

@UI.lineItem: [{ label: 'ChangedBy' , position: 80 }] 

ChangedBy; 

@UI.lineItem: [{ label: 'ChangedAt' , position: 90 }] 

ChangedAt; 

} 

 

 

Step 4. 

 

On top of the basic view we have to behavior definition. 

 

managed implementation in class zbp_giri_i_empl_details unique; 

strict ( 2 ); 
define behavior for zgiri_i_empl_details //alias  

persistent table zgiri_t_emp_det 

lock master 

with additional save 

authorization master ( instance ) 

early numbering 

//etag master  

{ 

create ( authorization : global ); 

update; 

delete; 

field ( readonly ) Id; 

mapping for zgiri_t_emp_det 

{ 

ChangedAt = changed_at; 

ChangedBy = changed_by; 

CreatedAt = created_at; 

CreatedBy = created_by; 

CurrKey = curr_key; 

Department = department; 

Id = id; 

Name = name; 

Salary = salary; 

} 

} 

 

 

On top the consumption view i have create behavior definition for consumption view. 

 

projection; 

strict ( 2 ); 

define behavior for zgiri_c_empl //alias  

{ 

use create; 

use update; 

use delete; 

} 

 

Step 5. 

On top the behavior definition we have to create service definition. 

 

@EndUserText.label: 'service definition' 

define service Zgiri_rap_scn_ser { 

expose zgiri_i_empl_details; 

} 

 

Step 6. 

On top the service definition we have to create  service binding. 

 

Gireesh_Pg1_0-1757662782709.Png

Step 6. 

I'm implementing logic in this class. 

CLASS lsc_zgiri_i_empl_details DEFINITION INHERITING FROM cl_abap_behavior_saver. 

PROTECTED SECTION. 

METHODS save_modified REDEFINITION. 

ENDCLASS. 

CLASS lsc_zgiri_i_empl_details IMPLEMENTATION. 

METHOD save_modified. 

DATA lt_log TYPE STANDARD TABLE OF zgiri_t_ch_logs1. 

DATA lt_log1 TYPE STANDARD TABLE OF zgiri_t_ch_logs1. 

IF update-zgiri_i_empl_details iS NOT INITIAL. 

lt_log = CORRESPONDING #( update-zgiri_i_empl_details ). 

LOOP AT update-zgiri_i_empl_details ASSIGNING FIELD-SYMBOL(). 

ASSIGN lt_log[ id = -Id ] TO FIELD-SYMBOL() . 

* / NAME UPDATE......................................... 

if -%control-Name = if_abap_behv=>mk-on. 

-name = -Name. 

TRY. 

-id = cl_system_uuid=>create_uuid_x16_static( ). 

CATCH cx_uuid_error. 

"handle exception 

ENDTRY. 

APPEND  TO lt_log1. 
ENDIF. 
ENDLOOP. 
INSERT zgiri_t_ch_logs1 FROM TABLE _log1. 
ENDIF. 

ENDMETHOD. 

ENDCLASS. 
CLASS lhc_zgiri_i_empl_details DEFINITION INHERITING FROM cl_abap_behavior_handler. 

PUBLIC SECTION. 
PRIVATE SECTION. 

METHODS get_instance_authorizations FOR INSTANCE AUTHORIZATION 

IMPORTING keys REQUEST requested_authorizations FOR zgiri_i_empl_details RESULT result. 

METHODS get_global_authorizations FOR GLOBAL AUTHORIZATION 

IMPORTING REQUEST requested_authorizations FOR zgiri_i_empl_details RESULT result. 

METHODS earlynumbering_create FOR NUMBERING 

IMPORTING entities FOR CREATE zgiri_i_empl_details. 
ENDCLASS. 

CLASS lhc_zgiri_i_empl_details IMPLEMENTATION. 


METHOD get_instance_authorizations. 

ENDMETHOD. 

METHOD get_global_authorizations. 

ENDMETHOD. 

METHOD earlynumbering_create. 

DATA(lt_entities) = entities. 

DELETE lt_entities WHERE Id IS NOT INITIAL. 

TRY. 

cl_numberrange_runtime=>number_get( 

EXPORTING 

nr_range_nr="01" 

object="/DMO/TRV_M" 

quantity = CONV #( lines( lt_entities ) ) 

IMPORTING 

number = DATA(lv_latest_num) 

returncode = DATA(lv_code) 

returned_quantity = DATA(lv_qty) 

). 

CATCH cx_nr_object_not_found. 

CATCH cx_number_ranges INTO DATA(lo_error). 

LOOP AT lt_entities INTO DATA(ls_entities). 

APPEND VALUE #( %cid = ls_entities-%cid 

%key = ls_entities-%key ) 

TO failed-zgiri_i_empl_details. 

APPEND VALUE #( %cid = ls_entities-%cid 

%key = ls_entities-%key 

%msg = lo_error ) 

TO reported-zgiri_i_empl_details. 

ENDLOOP. 

EXIT. 

ENDTRY. 

ASSERT lv_qty = lines( lt_entities ). 

* DATA: lt_travel_tech_m TYPE TABLE FOR MAPPED EARLY yi_travel_tech_m, 

* ls_travel_tech_m LIKE LINE OF lt_travel_tech_m. 

DATA(lv_curr_num) = lv_latest_num - lv_qty. 

 

LOOP AT lt_entities INTO ls_entities. 

lv_curr_num = lv_curr_num + 1. 

APPEND VALUE #( %cid = ls_entities-%cid 

ID = lv_curr_num ) 

TO mapped-zgiri_i_empl_details. 

ENDLOOP. 
ENDMETHOD. 
ENDCLASS. 

 

The output. 

 

Gireesh_Pg1_1-1757669465661.Png

Im going to update the this value. 

Here the updated value  we can see. 

Gireesh_Pg1_2-1757669524158.Png

And we see in the chang log table. 

Gireesh_Pg1_3-1757669550993.Png

In conclusion, using a dedicated change log table provides an efficient and practical way to track data modifications without the heavy storage cost of maintaining full historical snapshots. By recording only essential metadata such as key fields, change type, user, and timestamps, it creates a lightweight yet reliable audit trail. Combined with RAP determinations during the save sequence, this approach ensures that all changes are captured before commit, enabling transparency, compliance monitoring, and easier troubleshooting. Overall, it strikes the right balance between auditability and performance, making it a smart choice for scenarios where full data history is unnecessary.

thank you.

 

 

 



Source link

Leave a Reply

Your email address will not be published. Required fields are marked *