DWDM: Enjoy demo center

The enjoy controls are old, but still much in use.

If you need to re-use and idea and code, you can use transaction DWDM: the Enjoy Demo Center.

Double clicking program name will show the ABAP code on the right.

Double clicking on the title will give you the output of the example code.

The HTML control as WWW browser can be used to test the internet connectivity from your SAP server to internet.

Some developers might have restrictions on their laptop and use this program to browse.... 

Reading content data from batch job variants

In quite some cases the basis team is asked: in which batch job variant is this company code XXXX used? Or we need to add another sales organization to all the batch jobs, can you provide us a list with jobs using sales organization YYYY?

Some hints are given in this blog.

But no real solution.

Continue reading for a custom code solution!

Custom program to scan batch job variant content

If you load the program in the next section, create texts so that the start screen looks like this:

First test program on small batch of programs with know variants.

Example search all programs starting with ZA for the variant text US:

Result is list of program and variants with the key word:

Custom program coding

*&---------------------------------------------------------------------*
*& Report ZVARSEARCH
*&---------------------------------------------------------------------*
*&
*&---------------------------------------------------------------------*
REPORT ZVARSEARCH.

* _____________________________________________________________________
*|                              T A B L E S                            |
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
TABLES: trdir, tadir.

* _____________________________________________________________________
*|                              T Y P E S                              |
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
TYPES: BEGIN OF ty_source,
         line(255) TYPE c,
       END OF ty_source.

TYPES: BEGIN OF ty_objname,
         obj_name TYPE sobj_name,
       END OF ty_objname.

TYPES: BEGIN OF ty_variant,
         variant TYPE variant,
       END OF ty_variant.

* _____________________________________________________________________
*|              I T A B S  & W O R K A R E A S                         |
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
DATA: gt_selop       TYPE STANDARD TABLE OF    vanz,
      gt_params      TYPE STANDARD TABLE OF    vanz,
      gt_params_nonv TYPE STANDARD TABLE OF    vanz,
      gt_selop_nonv  TYPE STANDARD TABLE OF    vanz,
      gs_vanz        TYPE                      vanz,
      lv_text        TYPE                      string,
      gv_report      TYPE                      vari_reprt,
      mv_report      TYPE                      vari_reprt,
      gt_variant     TYPE STANDARD TABLE OF    ty_variant,
      gs_variant     TYPE                      ty_variant,
      gv_program     TYPE                      syrepid,
      gv_subrc       TYPE                      sysubrc,
      gt_reports     TYPE STANDARD TABLE OF    trdir,
      gs_reports     TYPE                      trdir,
      gt_valuetab    TYPE STANDARD TABLE OF    rsparams,
      gt_objname     TYPE STANDARD TABLE OF    ty_objname.

FIELD-SYMBOLS:
      <fs_vanz>      TYPE vanz.
* _____________________________________________________________________
*|                 S E L E C T I O N - S C R E E N                     |
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
SELECTION-SCREEN BEGIN OF BLOCK aa WITH FRAME.
SELECTION-SCREEN BEGIN OF BLOCK bb WITH FRAME TITLE text-t01.
PARAMETERS:     ra_srch   RADIOBUTTON GROUP a1
                             USER-COMMAND tab1 DEFAULT 'X',
                ra_srch2  RADIOBUTTON GROUP a1,
                ra_wday   RADIOBUTTON GROUP a1,
                ra_synt   RADIOBUTTON GROUP a1,
                ch_all   AS CHECKBOX  MODIF ID a2.
SELECTION-SCREEN END OF BLOCK bb.
SELECT-OPTIONS: so_prog   FOR trdir-name.
PARAMETERS:     p_string  TYPE s_text       MODIF ID a1.
SELECTION-SCREEN SKIP.
SELECTION-SCREEN BEGIN OF BLOCK cc WITH FRAME.
PARAMETERS:     pa_prog   TYPE program,
                pa_local  AS CHECKBOX.
SELECTION-SCREEN END OF BLOCK cc.
SELECTION-SCREEN END OF BLOCK aa.

* _____________________________________________________________________
*|           A T  S E L E C T I O N - S C R E E N  O U T P U T         |
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
AT SELECTION-SCREEN OUTPUT.

  LOOP AT SCREEN.
    CASE screen-group1.
      WHEN 'A1'.

        IF ra_srch  IS INITIAL
        AND ra_srch2 IS INITIAL.
          CLEAR p_string.
          screen-input = '0'.
        ELSE.
          screen-input = '1'.
        ENDIF.
      WHEN 'A2'.
        IF ra_synt = 'X'.
          screen-input = '1'.

        ELSE.
          CLEAR ch_all.
          screen-input = '0'.
        ENDIF.
    ENDCASE.
    MODIFY SCREEN.
  ENDLOOP.

* _____________________________________________________________________
*|                 S T A R T - O F - S E L E C T I O N                 |
* ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
START-OF-SELECTION.
  IF ( NOT ra_srch  IS INITIAL OR NOT ra_srch2 IS INITIAL )
  AND p_string IS INITIAL.
    MESSAGE e001(00) WITH 'No string entered'.
  ENDIF.

  PERFORM select_programs.
  PERFORM select_variants.

END-OF-SELECTION.

*&---------------------------------------------------------------------*
*&      Form  SELECT_PROGRAMS
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM select_programs.

  DATA: lv_tabix   TYPE   sytabix,
        lv_lines   TYPE   i.

*-Only executable programs are taken into account
  IF ch_all IS INITIAL.
    SELECT * FROM trdir
       INTO TABLE gt_reports
         WHERE name IN so_prog
                     AND subc = '1'.

*-For syntax checking you can also include other program types
  ELSE.
    SELECT * FROM trdir
      INTO TABLE gt_reports
        WHERE name IN so_prog.
  ENDIF.

  SORT gt_reports BY name.
  DESCRIBE TABLE gt_reports LINES lv_lines.

*-check if the user wants to start from a certain program
*-(so skip all preceding programs)
  IF NOT pa_prog IS INITIAL.

    READ TABLE gt_reports WITH KEY name = pa_prog
     TRANSPORTING NO FIELDS.
    IF sy-subrc = 0.
      lv_tabix = sy-tabix + 1.
      IF lv_tabix < lv_lines.
*-      Delete all preceding reports including the start from report
        DELETE gt_reports FROM 1 TO lv_tabix.
      ENDIF.
    ENDIF.

  ENDIF.

  IF gt_reports[] IS INITIAL.
    MESSAGE s001(00) WITH 'No reports selected'.
    WRITE:/ 'No reports selected'.
  ENDIF.

ENDFORM.                    " SELECT_PROGRAMS
*&---------------------------------------------------------------------*
*&      Form  SELECT_VARIANTS
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
FORM select_variants .

  DATA: lt_results     TYPE STANDARD TABLE OF rsvobs,
        lv_found       TYPE                   flag.

  REFRESH gt_objname.

  CHECK NOT gt_reports[] IS INITIAL.

*-retrieve already all details for quicker reading
  IF pa_local = 'X'.                         "Exclude local programs
    SELECT obj_name INTO TABLE gt_objname
      FROM tadir
      FOR ALL ENTRIES IN gt_reports
      WHERE pgmid = 'R3TR'
        AND object = 'PROG'
        AND obj_name = gt_reports-name.
  ELSE.                                      "Include local programs
    SELECT obj_name INTO TABLE gt_objname
      FROM tadir
      FOR ALL ENTRIES IN gt_reports
      WHERE pgmid = 'R3TR'
        AND object = 'PROG'
        AND obj_name = gt_reports-name
        AND devclass <> '$TMP'.
  ENDIF.

  LOOP AT gt_reports INTO gs_reports.

    READ TABLE gt_objname
      WITH KEY obj_name = gs_reports-name
        TRANSPORTING NO FIELDS.
    CHECK sy-subrc = 0.

    gv_program = gv_report = gs_reports-name.

*=====================================================================*
*-  PERFORM A SYNTAX CHECK FOR PROGRAM
*=====================================================================*
*-  Get the source code of the report for syntax checking
    PERFORM program_syntax_check USING    gv_program
                                 CHANGING gv_subrc.

*-  Skip programs with syntax errors for further variant checking
    IF gv_subrc <> 0.
      IF ra_synt = 'X'.
        MESSAGE s000(3w) WITH 'SYNTAX ERROR==>' gv_report.
        WRITE:/      gv_report,
                  50 'CONTAINS SYNTAX ERROR'.
      ELSE.
        CONTINUE.
      ENDIF.
    ENDIF.

*---------------------------------------------------------------------*
*-  Only process variants for select-options search and working days
*---------------------------------------------------------------------*
    CHECK ra_srch = 'X' OR ra_srch2 = 'X' OR ra_wday = 'X'.

*-  Select variants for a program
*-  (exclude the very old ones and also the standard SAP ones)
    SELECT variant INTO TABLE gt_variant
      FROM varid
          WHERE report = gv_report
            AND ( edat > 20100101  OR  aedat > 20100101 )
            AND ( ename <> 'SAP'   AND aename <> 'SAP'  ).

    CHECK NOT gt_variant[] IS INITIAL.
    REFRESH lt_results.

*-  Process all variants
    LOOP AT gt_variant INTO gs_variant.
      CLEAR lv_found.

*-    Give a message to indicate which program/variant is being checked
*-    (comes in handy in case the program cancels during the check as
*-    you can then restart this program starting from the object that
*-    dumped)
      MESSAGE s000(3w) WITH 'Checking' gv_report '-' gs_variant-variant.

      CALL FUNCTION 'RS_VARIANT_CONTENTS'
        EXPORTING
          report                      = gv_report
          variant                     = gs_variant-variant
          no_import                   = ' '
          execute_direct              = ''
        TABLES
          l_params                    = gt_params
          l_params_nonv               = gt_params_nonv
          l_selop                     = gt_selop
          l_selop_nonv                = gt_selop_nonv
          valutab                     = gt_valuetab
       EXCEPTIONS
         variant_non_existent        = 1
         variant_obsolete            = 2
         OTHERS                      = 3.

      CHECK sy-subrc = 0.

*=====================================================================*
*-    SEARCH VARIANTS FOR A CERTAIN FIELD VALUE
      IF ra_srch = 'X'.
*=====================================================================*
        FIND FIRST OCCURRENCE OF p_string
        IN TABLE gt_valuetab
        IN CHARACTER MODE.
        IF sy-subrc = 0.
          CONCATENATE 'String' p_string 'found'
             INTO lv_text SEPARATED BY space.
          MESSAGE s000(3w) WITH 'FOUND:' gv_report
                                gs_variant-variant lv_text.

          WRITE:/   'FOUND:',
                  7 gv_report,
                 50 gs_variant-variant,
                 80 lv_text.
        ENDIF.

*=====================================================================*
*-    SEARCH VARIANTS FOR A CERTAIN FIELD NAME OR FIELD DESCRIPTION
      ELSEIF ra_srch2 = 'X'.
*=====================================================================*
*-      Check select-options field names and descriptions for a
*-      certain string
        LOOP AT gt_selop ASSIGNING <fs_vanz>.
          FIND FIRST OCCURRENCE OF  p_string
          IN <fs_vanz>-name IN CHARACTER MODE.
          IF sy-subrc = 0.
            lv_found ='X'.
            EXIT.
          ENDIF.
        ENDLOOP.

        IF lv_found IS INITIAL.
          LOOP AT gt_selop_nonv ASSIGNING <fs_vanz>.
            FIND FIRST OCCURRENCE OF  p_string
            IN <fs_vanz>-name IN CHARACTER MODE.
            IF sy-subrc = 0.
              lv_found ='X'.
              EXIT.
            ENDIF.
          ENDLOOP.
        ENDIF.

        IF lv_found IS INITIAL.
          LOOP AT gt_params  ASSIGNING <fs_vanz>.
            FIND FIRST OCCURRENCE OF p_string
            IN <fs_vanz>-name IN CHARACTER MODE.

            IF sy-subrc = 0.
              lv_found ='X'.
              EXIT.
            ENDIF.
          ENDLOOP.
        ENDIF.

        IF lv_found IS INITIAL.
          LOOP AT gt_params_nonv  ASSIGNING <fs_vanz>.
            FIND FIRST OCCURRENCE OF p_string
            IN <fs_vanz>-name IN CHARACTER MODE.

            IF sy-subrc = 0.
              lv_found ='X'.
              EXIT.
            ENDIF.
          ENDLOOP.
        ENDIF.

        IF lv_found = 'X'.
          CONCATENATE 'String' p_string 'found'
                      INTO lv_text SEPARATED BY space.
          MESSAGE s000(3w) WITH 'FOUND:' gv_report
                                gs_variant-variant lv_text.
          WRITE:/   'FOUND:',
                  7 gv_report,
                 50 gs_variant-variant,
                 80 lv_text.
        ENDIF.

*=====================================================================*
*-    SEARCH VARIANTS FOR VARIABLES THAT REQUIRE CALENDAR ENTRY
      ELSEIF ra_wday = 'X'.
*=====================================================================*
        LOOP AT gt_selop INTO gs_vanz
             WHERE vname <> ''.
          IF gs_vanz-vname CS 'XWD' OR gs_vanz-vname CS 'WDAY'.
            lv_found ='X'.
            EXIT.
          ENDIF.
        ENDLOOP.
        IF lv_found IS INITIAL.
          LOOP AT gt_selop_nonv INTO gs_vanz
               WHERE vname <> ''.
            IF gs_vanz-vname CS 'XWD' OR gs_vanz-vname CS 'WDAY'.
              lv_found ='X'.
              EXIT.
            ENDIF.
          ENDLOOP.
        ENDIF.
        IF lv_found IS INITIAL.
          LOOP AT gt_params INTO gs_vanz
               WHERE vname <> ''.
            IF gs_vanz-vname CS 'XWD' OR gs_vanz-vname CS 'WDAY'.
              lv_found ='X'.
              EXIT.
            ENDIF.
          ENDLOOP.
        ENDIF.
        IF lv_found IS INITIAL.
          LOOP AT gt_params_nonv INTO gs_vanz
               WHERE vname <> ''.
            IF gs_vanz-vname CS 'XWD' OR gs_vanz-vname CS 'WDAY'.
              lv_found ='X'.
              EXIT.
            ENDIF.
          ENDLOOP.
        ENDIF.

        IF lv_found = 'X'.
          MESSAGE s000(3w) WITH 'FOUND:' gv_report gs_variant-variant
                                'Calendar logic present'.
          WRITE:/   'FOUND:',
                  8 gv_report,
                 50 gs_variant-variant,
                 80 'Calendar logic present'.

        ENDIF.

      ENDIF.

    ENDLOOP.

  ENDLOOP.

ENDFORM.                    " SELECT_VARIANTS
*&---------------------------------------------------------------------*
*&      Form  PROGRAM_SYNTAX_CHECK
*&---------------------------------------------------------------------*
*       text
*----------------------------------------------------------------------*
*      <--P_LV_SUBRC  text
*----------------------------------------------------------------------*
FORM program_syntax_check   USING    p_program
                            CHANGING p_subrc.

  DATA: lt_source    TYPE STANDARD TABLE OF    ty_source.

  CLEAR p_subrc.
  REFRESH lt_source.

  READ REPORT gv_program INTO lt_source.

  CALL FUNCTION 'RS_SYNTAX_CHECK'
    EXPORTING
      i_program        = p_program
    IMPORTING
      o_error_subrc    = p_subrc
    TABLES
      i_source         = lt_source.

ENDFORM.                    " PROGRAM_SYNTAX_CHECK

ABAP escape functions

The escape function is used in IT systems to indicate a real value of a character in stead of the control function of the character. Example is the < character which means smaller than, but in HTML is also a control character. For more background read wikipedia.

In ABAP code you sometimes need to set a URL with these characters, or build a HTML text. Then you really need to use these rules.

Documentation of the Esacpe function in ABAP can be found in this URL.

Example is the following code:

cl_demo_output=>display(
  escape( val    = 'IF a < b.'
          format = cl_abap_format=>e_xml_text ) ).

The result will be IF a &lt; b. < is in xml replaced by escape character &lt;.

Demo program

A full list can be found in ABAP program DEMO_ESCAPE. Start the program and select the type you want to check (do select the Show Differences tick box):

Output is now show for the diverse characters:

Find batch jobs with deleted or locked step users

If a batch job step user is locked or deleted, that step will fail. To find batch jobs with deleted or locked step users, start program BTCAUX09:

This will give a full list of jobs that you might want to start analyzing for deletion:

Why clean up? You will most likely find a lot of jobs in Scheduled status that never ran and are planned very long time ago. All batch job related transactions will have to plough through this irrelevant data.

OSS notes

Notes:

ABAP code to call URL

In ABAP code you might need to reach out to a browser.

The code to call a URL is pretty simple:

DATA ld_url(1000).

ld_url = 'https://www.saptechnicalguru.com'.

CALL FUNCTION 'CALL_BROWSER'
  EXPORTING
    url = ld_url.

Simply construct your URL and use function “CALL_BROWSER”.

For a webdynpro to run in browser use this code:

CALL FUNCTION 'WDY_EXECUTE_IN_BROWSER'
   EXPORTING
     application         = 'ESH_SEARCH_RESULTS_UI'
EXCEPTIONS
     invalid_application = 1
     browser_not_started = 2
     action_cancelled    = 3
OTHERS              = 4.
IF sy-subrc <> 0.
  MESSAGE ID sy-msgid TYPE sy-msgty NUMBER sy-msgno WITH sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4 RAISING execution_error.
ENDIF.

Application ESH_SEARCH_RESULTS_UI is an example here of a web dynpro.

SAP Netweaver gateway FIORI system performance

SAP netweaver gateway is used to host FIORI apps. Attention must be paid to the generic system performance of the system to avoid FIORI users to complain about performance.

Regular clean up jobs

Run program /IWFND/R_SM_CLEANUP in batch to clean up the application log. See note 2499354 – Report /IWFND/R_SM_CLEANUP. You can run with clean up scenario * for all, or select a specific scenario:

/IWFND/CLEANUP_APPSLOG will clean up the application log.

/IWFND/SUPPORT_UTILITIES will clean up support utilities.

See more on periodic tasks on help.sap.com.

See OSS note 2620821 – Periodical jobs and corresponding reports to also run programs /IWBEP/SUTIL_CLEANUP and /IWBEP/R_CLEAN_UP_QRL regularly (daily).

Run report /UI2/PERS_EXPIRED_DELETE weekly to clean up old personalization data (see note 2031444 – Cleanup of expired Fiori personalization data on the frontend server).

Cache settings

Metadata cache settings

In customizing go to this path:

Setting should look like following in a productive system:

In a development system you should de-activate this cache.

HTTP/2 usage

Check if you have enabled HTTP/2 already. If not, activate it. See this blog.

Log level settings

In a productive system you can reduce data footprint and improve performance by reducing the log level settings. Only in case of issues, you can increase the log levels again.

To avoid excessive SLG1 logging of type “MESSAGE_TEXT”, make sure to apply solution from OSS note 3247600 – Fiori: /IWFND/MED170 – No service found for namespace ‘/IWBEP/’, name ‘MESSAGE_TEXT’, version ‘0001’.

Gateway error log

Go to transaction /n/IWFND/ERROR_LOG. Now select menu Error Log/Global Configuration. Now the configuration opens:

Set the Error log level in production to Secure. And check the days to realistic dates (settings above in the screen shot are per SAP advice).

Backend error log

Go to transaction /n/IWBEP/ERROR_LOG. Now select menu Error Log/Global Configuration. Now the configuration opens:

Set the Error log level in production to Secure. And check the days to realistic dates (settings above in the screen shot are per SAP advice).

Metering

Make sure you don’t keep all metering data too long. You can aggregate and delete it. See this blog.

Check search settings

Check your FIORI search settings. The setup of search is described in this blog and is very powerful. But search might not be needed at all, or most users want only to search for apps:

See note 2871580 – SAP Fiori Launchpad Settings: new Parameters for Enterprise Search for the settings to optimize, and SAP blog on explanation of the settings.

See note 2885249 – How to disable Enterprise Search in Fiori Launchpad to disable the enterprise search part.

See note 2051156 – Deactivation of search in SAP Fiori launchpad for deactivation.

Amount of tiles assigned to the user

The amount of tiles assigned to a user has a big impact on performance. Try to reduce the amount of tiles assigned to the user as minimal as possible.

See OSS notes 2829773 – Fiori Launchpad performance with a large volume of Tiles and 2421371 – Understanding Launchpad performance Issues.

Tables that are growing

Specific notes and solutions for tables that are growing fast in a netweaver gateway system:

Sizing

This should be simple one, but it isn’t. Sizing of Netweaver Gateway should not be done based on day or week average. Determine your peak times. And at those peak times check the CPU and memory load. If you take averages that include weekend and night, then system sizing might be totally fine. But to avoid complaints, you must be able to handle the peak load.

Full checklist

SAP has a checklist called “SAP Fiori launchpad best practice verification checklist”. Follow this link for the document.

Good other blog with checklist: follow this link.

List all user documenation

On the SU01 user maintenance screen there is a nice tab to capture documentation for that user. But how to list all documentation for all users?

List of all user documentation

To get the user documentation listing program, apply OSS note 3113345 – SUIM | Reporting for User Documentation. This will deliver program SUIM_SHOW_USDOCU:

Run the program for your selection to get the result list:

Click on a documentation line to see all the history.

OSS notes

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).

Functionality issues after HANA database migration

Functional issues after HANA database migration are rare. Some might occur on an ECC system if there are minor bugs or issues in the HANA database optimized routines.

Example OSS notes:

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

SAP Readiness check for Cloud ALM

SAP will stop supporting SAP solution manager by 31.12.2027. All its functions will be migrated to SAP Cloud ALM.

The SAP readiness check for Cloud ALM will check the usage of current functions in your SAP solution manager and will validate if replacements in Cloud ALM are already present.

Since Cloud ALM is constantly growing in functionality you better run this check yearly. It is up to each customer to decide to move to SAP Cloud ALM for part of the functions or to wait until all functions are available.

There are other readiness checks as well:

Preparation in SAP solution manager

Apply the latest version of SAP note 3236443 – SAP Readiness Check for SAP Cloud ALM to your SAP solution manager system. Run program /SDF/RC_ALM_COLLECT_DATA in your solution manager production system.

It might be that your RFC for destination WEBADMIN is not setup correctly. That will cause a short dump.

If you are not using Trace Analysis function, you can remove code to this call in the local definition of class /SDF/CL_RC_ALM:

Running the check

Run program /SDF/RC_ALM_COLLECT_DATA in your solution manager production system. Select the option Schedule Analysis:

When the job is finished select Download Analysis Data and save the file.

Upload the result file on the Readiness page in SAP for me on this URL.

Result of the check

After the upload, wait up to 1 hour for SAP to process the results. For full explanation of the checks, read this SAP blog. Short description is below:

Top left you get an overview of the capabilities that were detected that are currently in use in Solution manager, or were used in the past:

Below is the most important overview. This shows if your used functions are available on Cloud ALM or will come in the near future, or only on the far Vision future:

SAP Cloud ALM positioning

Read more on SAP Cloud ALM positioning in this blog.

SAP Cloud ALM activation

Read more on SAP Cloud ALM activation in this blog.

Solution manager clean up

For parts of solution manager that you don’t use, you can perform the technical clean up.