Custom code adjustments for HANA database migration

If you convert ECC to S4HANA you need to execute custom code adjustments for both HANA database migration and for functional application changes. This can be read in this blog and this blog.

If you only want to migrate an existing database to HANA for a netweaver ABAP stack (either standalone or for SAP ECC), you will also need to adjust custom code.

Questions that will be answered in this blog are:

  • Which custom code ABAP changes to I need to perform mandatory for a HANA database migration?
  • Which custom code ABAP changes are highly recommended to perform for a HANA database migration?
  • Which other tools should I use to help to smoothen the HANA database migration?

Mandatory custom ABAP changes for HANA database migration

There are mandatory ABAP changes to be made for HANA database migration. The main ones are:

  • Native SQL statements
  • Use of Database hints
  • Search in pool and cluster tables
  • Use of ADBC interface
  • Search for problematic statements without ORDER BY

The first few will not appear too much and are relatively easy to fix.

The last one: the statements without ORDER BY needs some explanation. Some current custom code might work properly with the current database, since some database will present the data to the ABAP application server in a specific sorted way. When migration to HANA database the HANA database might present the same records to the ABAP application server, but in a different sorting or in a random order. This might lead to issues in further handling in custom code. The solution is to analyze the code and to add explicit sorting as per need of the custom program. To scan the usage in live system, see below chapter on SRTCM.

All these changes can be detected with the SCI variant FUNCTIONAL_DB:

Run this SCI variant via the ATC tool on your custom code:

Wait for the run to finish and go to the results. The best overview is when you click the Statistics View button:

Clicking on an item will drill down to the details.

Performance related coding changes for HANA database migration

The second set of custom code changes is from the performance side. For this set you need to run the ATC tool with SCI variant PERFORMANCE_DB:

The PERFORMANCE_DB variant has 2 main parts: mandatory fixes, good to fix.

The mandatory fix is the unsecure use of SELECT FOR ALL ENTRIES. If this is not properly checked, it might blow up the system:

What happens here? If in the current database the SELECT FOR ALL ENTRIES for whatever reason is not giving results this might be running fine. But on HANA the entire table is read in this case. To scan the usage in live system, see below chapter on SRTCM.

The other part is the performance best practices for HANA:

This ATC run can yield a very long working list:

Where to start? Since even the priority 1 and 2 can yield a very long list.

Use the SQLM and SWLT tools. These tools will help you to prioritize the ATC run result from the PERFORMANCE_DB variant. SQLM will take statistics data from production. You start with the heavy used programs. SWLT will combine the heavy use with the ATC run. The output is the heavy used program which can be improved.

SRTCM tool

The SRTCM tool is specifically designed to scan for 2 main issues: Empty table in FOR ALL ENTRIES clause and Missing ORDER BY or SORT after SELECT. The tool is run on a productive system and will list the actual usage in a productive system.

To switch on start transaction SRTCM and press the Activate Globally button.

Let the tool run, and later Display Results from either running system or snapshot:

Show results;

Clicking on the line will jump to the direct code point.

Note for Oracle as source database: 3209584 – RTM: RTM_PERIODIC_JOB canceled with runtime error SQL_CAUGHT_RABAX (ORACLE).

Custom code decommissioning

SAP solution manager offers a custom code decommissioning cockpit tool. This tool you can use to delete unused custom code. Unused code does not need to be migrated, which will save you effort.

SAP references

SREPO: compare multiple sources across systems

SREPO is a tool to compare multiple ABAP code programs across 2 systems.

The background can be found in OSS note 1368474 – System comparison tool SREPO Version 2.0.

Using SREPO tool

Start transaction SREPO. Enter the RFC between the 2 systems and the list of objects to compare:

Then press the button Object Intersection. Result list is a list of programs existing in either one or both the systems:

Select a single program and start the Version Comparison:

CVA: Code vulnerability analysis

CVA is a licensed SAP tool to scan custom code for potential security issues.

CVA is built in code inspector and analysis is run via the ATC tool.

Questions that will be answered in this blog are:

  • What checks does CVA perform?
  • How to activate CVA?
  • Is CVA licensed?
  • Where to find more information on CVA?

Activating CVA

SAP CVA Code Vulnerability Analysis is a licensed tool. You need to activate it before you can use it. To activate run program RSLIN_SEC_LICENSE_SETUP:

The activation refers to OSS note 1855773 – Security checks for customer-specific ABAP programs which explains the license, restrictions, etc.

Call to SAP: if you really think security is important for your customers and their custom programs, don't ask money for CVA tool, but allow free usage!

Check the bug fix OSS notes below. Apply them before your first run.

Checks in detail

The SAP CVA checks can be seen in SCI variant SLIN_SEC:

And then open the variant and click the information button for details:

A full list of checks can also be found on this SAP blog.

And per netweaver version the checks are listed in OSS note 1921820 – SAP Code Vulnerability Analyzer – support package planning.

Setting up ATC variant and run

Start transaction ATC and press Schedule Run:

First create a new variant and refer to SCI variant SLIN_SEC:

Now schedule the run for your Z code:

The run can take a few hours.

More on ATC set up and running can be found in this blog.

Run results

Start transaction ATC and go to the results part:

Select your run:

The ATC result screen will show, but list can be very long:

Both Z programs and user exits will be shown (starting with S or X).

Press the Statistics View button top right to get a better overview:

The result list is now sorted per security item:

Don't let yourself be impressed by high numbers of the first run. Most issues are in old code: consider clean up. Focus on the priority 1 and priority 2 first. Finetune result set for priority 3 to lower the numbers.

Now you can zoom in to the issue per item by clicking on the line:

The details show the issue: hard coded user name. Clicking on the underlined code name in column Object Name will zoom into the code point to fix:

In this case hard coded break for a user. Fix is easy: delete the line of code.

Remote analysis

It is possible to use ATC remote analysis (see blog) for CVA. The full setup is explained in this SAP online help link. See also OSS note 2232083 – ATC/CI: SAP NetWeaver Application Server add-on for code vulnerability analysis – remote check runs – installation.

Checking license usage

Run program RSLIN_SEC_LICENSE_SETUP to check license usage:

Or run this from transaction SLIN_ADMIN.

SAP reference material

Generic presentation on SAP CVA can be found on this link.

CVA FAQ: follow this link.

CVA full list of checks: follow this link.

CVA as part of CI/CD development pipeline: follow this link.

ABAP code security issues explained: follow this link.

Bug fix and improvement notes

Bug fix and improvement OSS notes:

BTE events

BTE events are Business Transaction Events. These events can be used to put custom specific logic in ABAP code interface when this event occurs.

It is used by standard SAP, partner software, and you can create your own interfaces.

Pros and cons

The BTE can solve business specific issues in a graceful way with custom code. This is a large pro.

The biggest con is that the technique is hardly known. When there are issues inside the Z coding for BTE, they are tough to spot and to detect. Good documentation is required of the event usage (both on paper specification and inside the Z code).

BTE events

The main transaction for BTE events is FIBF:

The screen is indeed empty.

The main parts are below Settings and Environment.

To list all the events, choose Environment, Info System (P/S):

And the result screen:

If you select a line and press the Display Act Comp button, you can see the details, including the existence of a customer implementation:

Background and references

Many good blogs already exist. So no need to repeat here.

List of blogs and sites:

Search transaction for user-exit and BADI

As ABAP developer you need to search for a user-exit and/or BADI for a certain transaction.

The helper program below can help you here. Copy and paste the source code and run the program:

Enter the transaction code and let the program search. Results will show:

You can click on the exit or badi name to jump to the definition.

The program to search for BADI or user-exit

*& Enter the transaction code that you want to search through in order *
*& to find which Standard SAP User Exits exists. *

TABLES : tstc, "SAP Transaction Codes
         tadir, "Directory of Repository Objects
         modsapt, "SAP Enhancements - Short Texts
         modact, "Modifications
         trdir, "System table TRDIR
         tfdir, "Function Module
         enlfdir, "Additional Attributes for Function Modules
         tstct, "Transaction Code Texts
*& Definition of Types *
TYPES: BEGIN OF t_badi_list,
         obj_name TYPE sobj_name,
         devclass TYPE devi_class,
         dlvunit  TYPE dlvunit,
         imp_name TYPE exit_imp,
         packname TYPE devclass,
         dlvunit2 TYPE dlvunit,
         text     TYPE sxc_attrt-text,
       END OF t_badi_list.
TYPES: BEGIN OF t_badi_list2,
         obj_name TYPE sobj_name,
         devclass TYPE devi_class,
         dlvunit  TYPE dlvunit,
       END OF t_badi_list2.
*& Data Declaration *
DATA: lt_badi_list  TYPE TABLE OF t_badi_list,
      lt_badi_list2 TYPE TABLE OF t_badi_list2,
      ls_badi_list  TYPE t_badi_list OCCURS 0 WITH HEADER LINE,
      ls_badi_list2 TYPE t_badi_list2.
RANGES: r_badi FOR tadir-obj_name ,
rt_badi FOR tadir-obj_name .
*& Variables *
       p_trkey LIKE trkey.
DATA : field1(30),
count TYPE p.
DATA : v_devclass  LIKE tadir-devclass,
       p_devclass  LIKE tadir-devclass,
       p_old_langu LIKE sy-langu,
       p_mod_langu LIKE sy-langu.
*& Selection Screen Parameters *
PARAMETERS : p_tcode LIKE tstc-tcode OBLIGATORY.
*& Start of report *
* Validate Transaction Code
  SELECT SINGLE * FROM tstc WHERE tcode EQ p_tcode.
*Find Repository Objects for transaction code
  IF sy-subrc EQ 0.
    SELECT SINGLE * FROM tadir WHERE pgmid = 'R3TR'
    AND object = 'PROG'
    AND obj_name = tstc-pgmna.
    MOVE: tadir-devclass TO v_devclass.
    IF sy-subrc NE 0.
* This section is used if a FGR is involved\!
          global_lock             = 'X'
          object                  = p_tcode
          object_class            = 'TRAN'
          mode                    = 'SHOW'
          language_upd_exit       = 'RS_TRANSACTION_LANGUAGE_EXIT'
          suppress_language_check = space
          new_master_language     = p_old_langu
          modification_language   = p_mod_langu
          transport_key           = p_trkey
          devclass                = p_devclass
          canceled_in_corr        = 1
          OTHERS                  = 2.
      IF sy-subrc = 0. " Success
        MOVE: p_devclass TO v_devclass.
      ELSE. " For the case that nothing is found\!
        SELECT SINGLE * FROM trdir WHERE name = tstc-pgmna.
        IF trdir-subc EQ 'F'.
          SELECT SINGLE * FROM tfdir WHERE pname = tstc-pgmna.
          SELECT SINGLE * FROM enlfdir WHERE funcname = tfdir-funcname.
          SELECT SINGLE * FROM tadir WHERE pgmid = 'R3TR'
          AND object = 'FUGR'
          AND obj_name = p_devclass.
          MOVE: tadir-devclass TO v_devclass.
*Find SAP Modifactions
    SELECT * FROM tadir INTO TABLE jtab
    WHERE pgmid = 'R3TR'
    AND object = 'SMOD'
    AND devclass = v_devclass.
    SELECT SINGLE * FROM tstct WHERE sprsl EQ sy-langu
    AND tcode EQ p_tcode.
    WRITE:/(19) 'Transaction Code - ', 20(20) p_tcode, 45(50) tstct-ttext.
    WRITE:/1 'The application area is:', v_devclass.
    IF NOT jtab[] IS INITIAL.
      WRITE:/(95) sy-uline.
      WRITE:/1 sy-vline, 2 'Exit Name', 21 sy-vline, 22 'Description', 95 sy-vline.
      WRITE:/(95) sy-uline.
      LOOP AT jtab.
        SELECT SINGLE * FROM modsapt
        WHERE sprsl = sy-langu
        AND name = jtab-obj_name.
        WRITE:/1 sy-vline, 2 jtab-obj_name HOTSPOT ON, 21 sy-vline , 22 modsapt-modtext,
        95 sy-vline.
      WRITE:/(95) sy-uline.
      DESCRIBE TABLE jtab.
      WRITE:/ 'No of Exits:' , sy-tfill.
      WRITE:/(83) sy-uline.
      WRITE:/1 sy-vline, 2 'Badi Name', 22 sy-vline, 23 'Description', 83 sy-vline.
      WRITE:/(83) sy-uline.
* select the BAdI Definitions from the tables sxc_exit and sxc_attr
      SELECT t~obj_name t~devclass tc~dlvunit sx~imp_name sat~text
      FROM ( ( ( ( tadir AS t
      tdevc AS tc ON t~devclass = tc~devclass )
      sxc_exit AS sx ON sx~exit_name = t~obj_name )
      sxc_attr AS sa ON sx~imp_name = sa~imp_name )
      sxc_attrt AS sat ON sx~imp_name = sat~imp_name )
      WHERE t~pgmid = 'R3TR'
      AND t~object = 'SXSD' "means BAdI
      AND t~devclass = v_devclass "narrow down seach with Dev.Class
      AND sat~sprsl = sy-langu.
      SORT lt_badi_list.
* create Ranges
      LOOP AT lt_badi_list INTO ls_badi_list .
        r_badi-sign = 'I' .
        r_badi-option ='EQ' .
        r_badi-low = ls_badi_list-imp_name .
        r_badi-high = ls_badi_list-imp_name .
        APPEND r_badi TO rt_badi .
* select the implementations
      SELECT t~obj_name t~devclass tc~dlvunit
      FROM tadir AS t
      tdevc AS tc ON t~devclass = tc~devclass
      FOR ALL ENTRIES IN rt_badi
      WHERE t~obj_name = rt_badi-low
      AND t~pgmid = 'R3TR'
      AND t~object = 'SXCI'.
      WRITE:/(83) sy-uline.
      count = '0'.
      LOOP AT lt_badi_list INTO ls_badi_list .
        WRITE:/1 sy-vline, 2 ls_badi_list-obj_name HOTSPOT ON, 22 sy-vline,
        23 ls_badi_list-text, 83 sy-vline.
        count = count + 1.
      WRITE:/(83) sy-uline.
      DESCRIBE TABLE ls_badi_list.
      WRITE:/ 'No of BADIs:' , count.
      WRITE:/(95) 'No User Exit exists'.
    WRITE:/(95) 'Transaction Code Does Not Exist'.
*& Call SMOD or SE18 to lead the user to the selected exit or badi *
  IF field1(4) EQ 'JTAB'.
    SET PARAMETER ID 'MON' FIELD sy-lisel+1(10).
  ELSEIF field1(12) EQ 'LS_BADI_LIST'.
        exit_name = sy-lisel+1(20)

Code and table generation

In some cases you need to regenerate specific coding and tables. An SGEN is too extensive for your situation.

Regenerate programs

Use program TOUCHSRC:

Or worst case program TOUCHALL:

Regenerate tables

For table regeneration run program TOUCHTAB:

And TOUCHINC for includes in table structures:


Background OSS notes:

Best practice notes:

TRDIR and TADIR: tables behind programs and tables

TRDIR and TADIR are the tables behind programs and table data.

The below section is for experts only. Sometimes direct interception in TRDIR or TADIR is needed to solve nasty upgrade and support package issues. But if you don't know what you are doing: don't touch and raise message to SAP.

TADIR: development objects

TADIR contains the development objects list.

For example you want to know how many Z classes are created in your system, search in TADIR with SE11 and count the records:

Using TADIR with a search on DEVCLASS $TMP will give you a list with all programs in the $TMP (temp) space.

TADIR also has information about the original system. To change: follow the instructions in this blog.

TADIR does not contain a program editor lock. This is stored in table PROGDIR. See more in this blog.

Background notes on TADIR:

TRDIR: source code

TRDIR is a view on table REPOSRC. REPOSRC contains the actual ABAP source codes in RAWSTRING format. In some cases inconsistencies between TRDIR and TADIR might happen (mainly during upgrades). Direct interception on TADIR or TRDIR level might be needed, if you know what you are doing.

Transaction STDR can be used to check consistency:

Background notes on TRDIR:

Clean ABAP code ATC variant

Clean ABAP is the ABAP variant of the clean code principles. All background on clean ABAP code can be read in this blog.

This blog will explain how to upload the ABAP coding for the Clean ABAP ATC variant in your system and activate it.

Load ABAP Git code

To load the ATC variant code for clean ABAP you first need to install the ABAP Git code. Follow the instructions in this blog to do so. Simplest is the offline variant.

Download the ABAP clean code package

Now go to the Github code pal site for ABAP clean code and download the package:

Select the button Code and choose the option Download ZIP.

Upload the package

Now start the ABAP git that you loaded in your first step. Choose the option New Offline:

Give the repository a name and select a package:

Then push the button Create Offline Repo.

Now select Import Zip:

Import the file you downloaded in step 2 from the code pal site.

Next step is the Pull zip:

You might get a screen with differences. Do not select anything there, only press Ok.

Then wait until all the Y objects are pulled into the system. This might take 5 to 10 minutes.

Activating the SCI checks

Now start transaction SCI. Select menu option Code Inspector, Management of, Tests. Select all the newly load Y checks for Clean ABAP code:

Important now: Save them!

Now you can create a global SCI variant:

Select all the Clean code ABAP checks and save the variant:

You might get weird issues upon saving for other items, like for example missing CL_CI_CATEGORY_TOP. In that case, go to transaction SE16 -> look for table SCITESTS -> and look for CL_CI_CATEGORY_TOP if there is no entry. Enter the table SCITESTS and click "Create Entry", add CL_CI_CATEGORY_TOP entry and save.

Test and usage

Take a program you want check. Then select menu option Program, Check, ABAP Test Cockpit with….:

Select the ZCLEAN_ABAP SCI check we created above. Run the checks.


Tip: click on the blue line to jump to the Clean Code site exactly explaining about the issue.

Clean ABAP

Clean ABAP is the ABAP implementation of Clean code. Clean code is one of the key principles to adhere to when going Agile. Clean code is part of agile software development craftmanship. Read more on clean code in the original book.

Clean ABAP reference site

Clean ABAP is published and maintained on a dedicated Clean ABAP Github site.

The site itself is excellent and also has a special chapter how to best start with Clean ABAP.

The site is extensive and might be overwhelming. If you are a more traditional person, you can also read the SAP Press book on Clean ABAP code.

Blog on SAP site on clean ABAP can be found here.

Patterns and anti-patterns

The Clean ABAP explanation on the site contains both patterns (how you should do) and anti-patterns (how you should not do).

Anyhow the Clean ABAP principles are fully built on Object Orientation. That is a must.

Introducing Clean ABAP in your organization

Regardless if your organization is doing Agile or Waterfall development, or other development methodologies, Clean ABAP can be applied anyhow.

First step is to embrace the Clean ABAP as a principle direction. It will take time to get there. Not all developers will pick up as fast as you might want to. It also takes time to refactor old code to the Clean ABAP principles.

Discuss as developers as a team which part of the principles and improvements you want to pick up first. If you master a few, you can make it mandatory. Then take the next set. Some might pick up more at a higher pace. But keep the discussion going to improve and pick up every 2 weeks (sprint) at least 1 improvement item.

For a nice overview: read this SAP blog.

Peer review or pair programming: ATC variant

You can make the Clean ABAP code rules a part of your peer review or pair programming.

There is an ATC variant that can be uploaded that check for the clean ABAP code rules. Read this blog for instructions on how to do this.

Boy Scout rule

The boy scout rule is as follows: leave the place nicer than when you arrived, even though you didn’t make the mess. When you do this repetitively the world becomes a cleaner place.

This also applies to poor code: don’t just do your change, but take along some minor improvements as well. When you do this a couple of times, the poor code will improve every time towards good code.

But this principle you also need to embrace and explain. There might be unlucky situations where the clean up part might cause unexpected bug. This might happen in 0.01% of the cases. When it happens you might get resistance and pushback. But stand up for the principle, and simply correct the bug. It is worth it in the long run.


New input welcome, leave a comment!

What does the SAP abbreviation stand for?

  • SAP = Slow And Painful
  • SAP = Software Aus Pakistan
  • SAP = Shut up And Pay
  • SAP = Sanduhr Anschau Program
  • SAP = Schreibs Auf Papier
  • SAP = Suffer After Purchase
  • SAP = System against People
  • SAP = Start Applying Patches
  • SAP = Surrender and Pay
  • SAP = Sit and Panic
  • SAP = Severely Aged Programs
  • SAP = Submit (security bugs) and Pray
  • SAP = Sammelbecken Arbeitsloser Physiker -> German for Pool of Unemployed Physicists


Competence is limited, incompetence is unlimited
Below each level of incompetence there a next level of even worse incompetence
We don't need to remove the BigTruck button in STMS since nobody will be so stupid to start the ImportAll
Fundamental laws of stupidity:
1. Everybody underestimates the amount of stupid people
2. Stupidity is not related to any other characteristic of a person 
3. Stupid people damage others and themselves
4. Not-stupid people underestimate the damage of stupid people
5. Stupid people are more dangerous than smart criminals