You are on page 1of 28

Table of Contents

1. What is HANA-based BW transformation? ........................................................2


1.1 SAP HANA Optimized Transformations ....................................................3
1.2 Pre-requisites on going for HANA-based BW transformation conversion ......3
1.3 ABAP-based compared to HANA-based BW transformation........................3
2. Introducing ABAP Managed Database Procedure...............................................4
2.1 How HANA Stored Procedures are called between ABAP and HANA
Server4
2.2 AMDP (ABAP Managed Database Procedure) in HANA...............................5
2.3 AMDP used in a HANA-Based BW transformation .....................................5
2.4 Some points to note when working on AMDP ...........................................5
3. Creating your HANA-based BW transformation for the first time .........................6
4. Actual Examples - HANA-Based BW Transformation conversion...........................9
4.1 Example #1 – FIELD Routine ...................................................................9
4.1.1 How it was implemented in ABAP .............................................. 10
4.1.2 How it was converted in AMDP ................................................. 11
4.2 Example #2 – START Routine ................................................................ 13
4.2.1 How it was implemented in ABAP .............................................. 14
4.2.2 How it was converted in AMDP ................................................. 15
4.3 Example #3 – START Routine ................................................................ 16
4.3.1 How it was implemented in ABAP .............................................. 16
4.3.2 How it was converted in AMDP ................................................. 18
4.4 Example #4 – FIELD Routine ................................................................. 19
5. Recommendations ...................................................................................... 21
6. Appendix.................................................................................................... 22
6.1 Example #1 ........................................................................................ 22
6.1.1 ABAP Routine ......................................................................... 22
6.1.2 AMD Routine .......................................................................... 22
6.2 Example #2 ........................................................................................ 23
6.2.1 ABAP Routine ......................................................................... 23
6.2.2 AMDP Routine ........................................................................ 25
6.3 Example #3 ........................................................................................ 25
6.3.1 ABAP Routine ......................................................................... 25
6.3.2 AMDP Routine ........................................................................ 27
6.4 Example #4 ........................................................................................ 27
6.4.1 ABAP Routine ......................................................................... 27
6.4.2 AMDP Routine ........................................................................ 28

SAP HANA Based Transformation | 01.20.2017 | Page 1


HANA-Based BW Transformation
Author: Jeffrey Prado – SAP Senior BI Consultant

Most of the complex BW transformations (even on HANA DB) that requires complex routines are still built based on
ABAP which is executed in the ABAP application server. This constitutes huge performance overhead as the logic in
the transformation are processed row-by-row and field-by-field and data transfer happens twice between the ABAP
application server and the Database.

There has been a tremendous shift on how performance issues are addressed especially when you are now on HANA.
As Jonathan Andre noted on his blog Want to Avoid HANA AMDP Mistakes? READ THIS the rule-of-thumb is: do as
much as you can in the database to gain the best performance! This is what “HANA-pushdown” is all about. There
are several ways to achieve this and one way is via AMPD (ABAP Managed Database Procedure). From a SAP BWoH
perspective and as of SAP BW 7.4 SP6, you can now use AMDP to implement your HANA-based routines in your BW
transformation.

I will be explaining on this in more detail and lastly, will be sharing some of the actual examples I have done in my
previous project. I will go through each of these actual examples, explain what each routine is doing, how it was
implemented in ABAP and how I manage to convert it into AMDP.

1. What is HANA-based BW transformation?

HANA-based BW transformation pushes down a transformation logic directly into the HANA database system. HANA
push-down is achieved by:
• Standard Rule Types – When you use only standard formulas, Masterdata and DSO lookup in your BWoH
transformation.

• AMDP (ABAP Managed Database Procedure) – Traditionally, most or all your current BW transformation
routines are written in ABAP. If you want to push the entire transformation routines directly to HDB, you will
need to do this via AMDP which I will be explaining further in this document.

SAP HANA Based Transformation | 01.20.2017 | Page 2


1.1 SAP HANA Optimized Transformations

As of SAP BW 7.4 SP6, HANA-transformation is only available through HANA expert routines. While from SAP BW 7.5
SP4, you now have options to push down your transformation logic through Start, Field and End Routines with the
Expert routine already made available since SAP BW 7.4 Sp6.

1.2 Pre-requisites on going for HANA-based BW transformation conversion

As mentioned, HANA-pushdown for BW transformation is only available from SAP BW 7.4 SP6. Below are some points
that you need to consider before embarking on HANA-based BW transformation:
• Apply the required notes depending on the minimum version of your environment. You can use the link for
reference - https://wiki.scn.sap.com/wiki/display/BI/HANA+Transformations+-+Troubleshooting

• Strong knowledge in ABAP – You need to have a strong knowledge in ABAP or you need to have a strong
ABAPer with you to understand what the current ABAP-routine is doing.

• Strong HANA SQL scripting knowledge – It is important to gain strong knowledge on SQL scripting as the key
challenge you may face is how you will convert the existing typical ABAP-routines (e.g. Loop statements,
buffering into internal table) into single pure or series of HANA SQL scripts

1.3 ABAP-based compared to HANA-based BW transformation

ABAP-based HANA-based
Transformation Row by Row, Field by Field Package-based processing
Process Transformation Logic is processed Transformation Logic is processed
between ABAP application Server and entirely in HANA DB
DB
Objects Created Generates a standard ABAP Program in Generates the following: AMDP,
the ABAP Application Server Standard Stored Procedure in HANA DB
Required ABAP Scripting HANA SQL Scripting
Knowledge

SAP HANA Based Transformation | 01.20.2017 | Page 3


Let’s talk about the following differences highlighted above:
• Transformation Process – As mentioned earlier, ABAP-based transformation processes the data from the
source package row by row and field by field and the data is transmitted twice between the database and
application server twice! Compared to HANA-based where the entire data package is processed directly in
the HANA DB.

• Objects Created – ABAP-based generates the corresponding ABAP program while HANA-based generates a
standard HANA Stored procedure in the HANA DB

• Required Knowledge – You will need to develop your HANA SQL scripting should you embark on converting
your ABAP routines to HANA. Again, as mentioned the key challenge would be how to figure out converting
a typical ABAP script into pure SQL (avoiding loops, etc.).

Again, as mentioned, HANA-based transformation routines are implemented via AMDP. I will be discussing more of
this context in the next section.

2. Introducing ABAP Managed Database Procedure

AMDP is a class-based framework that is provided to push down database intensive processing directly to HANA DB.
Before I go deep further on AMDP let me just give you a background on how HANA push down is done before AMDP.

2.1 How HANA Stored Procedures are called between ABAP and HANA Server

Before AMDP was introduced, what the developers do is they follow a “BOTTOM-UP” approach:
1. The developers will create a standard stored procedure in the HANA DB which will contain databased
intensive processing via SQL scripts

2. The created standard stored procedure will be wrapped in a HANA Delivery Unit in HDB and will be exposed
as a Database Procedure Proxy and transported into the SAP Netweaver Application server through HANA
transport container.

3. This process takes place in each environment (DEV, QA and PRD).

4. So basically, you will need a delivery unit in HDB system and a standard SAP transport in SAP Netweaver to
move your transports across different environment

SAP HANA Based Transformation | 01.20.2017 | Page 4


2.2 AMDP (ABAP Managed Database Procedure) in HANA

With AMDP, it is now based on a “TOP DOWN” approach:


1. The developers will just need to implement their database-intensive processing via SQL scripts inside the
AMDP class framework
2. Once the AMDP class is activated, it will automatically generate a corresponding standard database
procedure in the HANA DB.
3. There is no delivery unit required in the process. You will only need to use the standard ABAP transport which
will be in an AMDP Class.

The following links will give you a good introduction and further learning about AMDP:
https://blogs.sap.com/2014/01/22/abap-managed-database-procedures-introduction/
https://help.sap.com/saphelp_nw74/helpdata/en/3e/7ce62892d243eca44499d3f5a54bff/frameset.htm

2.3 AMDP used in a HANA-Based BW transformation

When you are creating a HANA-based BW transformation routines (Start, Field, End or HANA-expert routines), the
BW framework generates an AMD class method for you to write your SQL scripts implementation.
This method can only be modified via ADT (ABAP Development Perspective) which is also driven by the BWMT (BW
Modelling tools) in the HANA Studio.

2.4 Some points to note when working on AMDP

Below are points that needs to be taken into consideration when working on AMDP:
1. You can access available DDIC views and table in your SAP BW system inside an AMDP Method

2. Not all SQL script functions are available in AMDP – you cannot use the full SQL scripting. Based on my
experience, you cannot use “TOP N” and “GROUP BY” clause in a subquery

3. You won’t be able to use Standard/Custom ABAP Function modules (i.e. CONVERT_TO_LOCAL_CURRENCY,
etc.) – alternatively, you can use a corresponding CE Functions or a Native HANA SQL Functions (i.e.
CE_CONVERT, CONVERT_CURRENCY)

SAP HANA Based Transformation | 01.20.2017 | Page 5


3. Creating your HANA-based BW transformation for the first time

Creating a HANA-based BW transformation is almost the same as the usual ABAP-based. The only difference is that
your routines are implemented in AMDP. Follow the steps below:
1. In your HANA studio, open the BW perspective and login to your BW project.
2. Open or create an existing transformation where you want to implement your first HANA-based routine

3. Say, for example in the transformation below, you will need to implement a HANA-based field routine for the
highlighted field.

4. Double-click on this field and you be prompted with enter your source fields as shown below:

5. When you entered the required source field, change the Rule Type to “Routines”. The system will prompt
you to either use ABAP or AMDP script for your routine.

SAP HANA Based Transformation | 01.20.2017 | Page 6


6. Click on AMDP Script and you will be prompted to choose an ABAP project

Choose an existing or create your new project and click OK.

7. The class framework below will be created for you:

8. This class framework contains the following:


a. Class Definition – Which contains structures and variable definitions that you will be using when you
start implementing your AMDP scripts. You will need to understand the following:
i. A class method’s definition created for you.

In this method, you will have the following variables:

SAP HANA Based Transformation | 01.20.2017 | Page 7


1. i_error_handling – a flag to indicate whether you have implemented an error
handler in your DTP.
2. inTab - which is like the SOURCE_PACKAGE that you see in an ABAP routine
3. outTab - which is like the RESULT_PACKAGE that you see in an ABAP routine
4. errorTab – where you populate your error message as part of your error handling

b. Class Implementation – The class generates a Class Method for you to implement you AMDP scripts

Inside this method is where you are going to implement your SQL scripts.

9. Enter your implementation script (SQL Script) as shown below:

The sample script above is using MARA as a lookup table. Notice the following:
a. OUTTAB = is your RESULT_PACKAGE from an ABAP routine point of view
b. INTAB = is your SOURCE_PACKAGE from and ABAP routine point of view

10. Activate your script by click on the button on top then activate the whole transformation.
11. You now have your first HANA-based transformation!

SAP HANA Based Transformation | 01.20.2017 | Page 8


4. Actual Examples - HANA-Based BW Transformation conversion

In this section, I will be sharing some of the actual example I have done in my previous project where I have converted
some of their ABAP routines to HANA via AMDP. I will be explaining each of the routine’s logic and how it was
implemented in ABAP and then how I managed to convert them to HANA. As I have mentioned in section 1.2, dealing
with AMDP involves heavy HANA SQL Scripting. The key challenge that you’ll face is to figure out how to convert an
ABAP routine (e.g. routines with LOOP, buffering data into an internal table, etc.) into pure HANA SQL script.

4.1 Example #1 – FIELD Routine

The first example below is a Field-routine which derives ZRT_STORE from a master data based on the source fields:
PLANT and RETAILSTOREID.

Sample Data:

Given the example source package and in the ZPA_SITE master data above, derive ZSTORE from ZPA_SITE master data
based on the following rules:
1. Rule#1 – Check for the combination from the source package in the master data where RETAILSTOREID =
RT_CUSTPL and PLANT = /BIC/ZPA_SITE. If exist, simply take the value of ZRT_STORE as the output
otherwise, apply Rule#2.

2. Rule#2 – Check from the master data based only on RETAILSTOREID where RETAILSTOREID = RT_CUSTPL.
This will give you multiple stores - take only the first instance of /BIC/ZRT_STORE.

SAP HANA Based Transformation | 01.20.2017 | Page 9


Based on the rules of the routine and the sample data above, this will give you the following output:

The first three records apply to Rule#2 and only the last record applies to Rule#1.

4.1.1 How it was implemented in ABAP


Below shows how this was implemented in the ABAP Field-Routine:

1. Rule#1 just simply takes /BIC/ZRT_STORE from the master data (/BIC/PZPA_SITE) where RT_CUSTPL =
RETAILSTOREID and /BIC/ZPA_SITE = PLANT.

2. Rule#2 takes only the first instance of /BIC/ZRT_STORE from the master data where RT_CUSTPL =
RETAILSTOREID.

SAP HANA Based Transformation | 01.20.2017 | Page 10


4.1.2 How it was converted in AMDP
Below is how this routine was converted into AMDP Field-routine:

As mentioned earlier compare to ABAP, HANA-based BW transformation is a packaged-based processing. So, this
field-routine is processed once per data package and not record-per-record. The above the script is broken down
based into a multiple result sets in the following local table variables:
1. LOOKUP
The first returned table is the LOOKUP table. This one table will take the result of the following SQL Statements
based on the two rules required in logic:
a. Rule#1:
Take ZRT_STORE from ZPA_SITE master data based on RETAILSTOREID and PLANT.

Based on the example data we have, this will give us one result:

SAP HANA Based Transformation | 01.20.2017 | Page 11


b. Rule#2:
Get only the first instance of ZRT_STORE from ZPA_SITE master data only based RETAILSTOREID =
RT_CUSTPL.

This statement has a sub-query, this sub-query will give you the following dataset based on the
sample data:

Noticed that in the sub-query, I used RANK() function to give me a row number based on RT_CUSTPL
and /BIC/ZPA_SITE.
Since Rule#2 requires taking only the first instance of ZRT_STORE, the main query takes care of this
by using the condition where Rank = 1. Thus, will give us the following results:

Results for Rule#1 and Rul#2 are merged using the UNION clause. Below is the result for the LOOKUP table:

SAP HANA Based Transformation | 01.20.2017 | Page 12


2. OUTTAB
The field-routine’s output will be in the OUTTAB return table. This simply used the LOOKUP table in the main
SQL script.

Based on this SQL script this will give us the final result:

4.2 Example #2 – START Routine

This next example is a START routine written in ABAP based on the following rules:
1. Restrict the source package records only for Sales Org based on the Sales Org entries in the BW Parameters
Master Data (ZPARAM) using parameter key = ‘ZASRECO2_SALESORG*’.
2. Exclude void transactions (ZRPA_VOID = ‘X’)

Below are the sample entries in the ZPARAM master data:

So, based on the entries in the master data, you’ll restrict the records in the source package only for Sales Orgs: 5000
to 5999; 6000 to 6999.

SAP HANA Based Transformation | 01.20.2017 | Page 13


4.2.1 How it was implemented in ABAP
Below is how this was implemented in and ABAP START Routine:

In the ABAP routine above, it uses either parameter key “ZASRECO2_SALESORG%” or “AM_SALESORG%” to get the
Sales Orgs values to restrict. There is a LOOP statement in the routine to apply the restriction.
And finally, it also removes all void transactions.

SAP HANA Based Transformation | 01.20.2017 | Page 14


4.2.2 How it was converted in AMDP
Below is how this Routine was converted into an AMDP START Routine:

You can also us local scalar variables in HANA SQLscript. In the above script, I used the “Declare” keyword to declare
variables for: lv_param – which holds the parameter key and v_count - which takes the number of records. So, the
script above does the following:
1. First, check which parameter key exist in the ZPARAM master data. Check for ZASRECO2_SALESORG
otherwise use AM_SALESORG.
2. The ZPARAM master data will give you SALES ORG entries based on our example:

3. These records are passed into the local table variable – it_param.
4. The final output which sits in the local table OUTTAB has the following restrictions:
a. A sub-query to restrict SALES ORG from the it_param local table
b. Exclude void transaction (a.”/BIC/ZRPA_VOID” <> ‘X’)

SAP HANA Based Transformation | 01.20.2017 | Page 15


4.3 Example #3 – START Routine

The third example is a START Routine that generates a sequence number for each POS transaction with discount
coupons applied in a store.
In the example source package below, POS transactions 123 and 124 (RPA_TNR = 123, 124) for stores 001 and 003
(/BIC/ZRT_STORE = 001, 002) has discount coupons (RPA_DID <> “”). And only transaction 125 (RPA_TNR = 125) do
not have discounts applied.

Given these POS transactions, generate a sequence numbers (as shown in the above output) for each discount coupon
for every transaction. So, looking at POS transaction 123 (RPA_TNR = 123) under store 001 (/BIC/ZRT_STORE = 001) it
has four discount coupons (RPA_ID = 112, 117, 119, 124). Noticed the output generates sequence numbers 1 to 4
(/BIC/ZRPA_FS = 1, 2, 3, 4). And the rest applies to POS transaction 124.

4.3.1 How it was implemented in ABAP


This is how the logic was implemented in an ABAP Routine:
The routine is broken into three parts:
1. Part 1:

This part collects all transactions with discounts (RPA_DID <> ‘’) from the source package and pass these
records into the following internal tables:
a. LT_COUPON_COUNT – holds the total number of coupons per transaction and store.
b. LT_COUPON_ID = holds unique records: Transaction (RPA_TNR) + Coupon ID (RPA_DID) + Store
(RT_LOCATIO)

SAP HANA Based Transformation | 01.20.2017 | Page 16


Below shows the output of the internal tables based on the code above (NOTE: ZRT_STORE = RT_LOCATIO):

2. Part 2:

This code then generates sequence numbers as required. From the source package, check if there are
transactions with discount coupons from internal table LT_COUPON_COUNT then start generating sequence
numbers from the internal table – LT_COUPON_ID.
The records with coupons and coupon count sits in the new internal table – LT_NEW_RECORDS. Records
from this internal table is processed in part three.

3. Part Three:

All coupon records with corresponding coupon count now sits in LT_NEW_RECORDS. This part deletes the
old ones in the source package table and replace with these new records.

SAP HANA Based Transformation | 01.20.2017 | Page 17


4.3.2 How it was converted in AMDP
This is how the ABAP routine was converted into AMDP:

Note that the fields: RT_LOCATIO (from ABAP) and /BIC/ZRT_STORE (AMDP) are the same. The script above is broken
down into two parts which is stored into two staging local tables:
1. COUPONCNT – generates sequence numbers (counters) for every transaction (RPA_TNR) and store
(/BIC/ZRT_STORE). Using the “Rank” function, which provides like a counter for every partition I have defined
in the script.
2. OUTTAB – will be the final output of this script. The local table COUPONCNT is used as a look up table to get
the corresponding counter value.

SAP HANA Based Transformation | 01.20.2017 | Page 18


4.4 Example #4 – FIELD Routine

SAP HANA Based Transformation | 01.20.2017 | Page 19


From the given source package, get the latest moving average price

4.4.1.1 How it was implemented in ABAP

4.4.1.2 How it was converted in AMDP

SAP HANA Based Transformation | 01.20.2017 | Page 20


5. Recommendations

1. Use standard formulas instead of routines as much as possible


By using standard formulas, you are already pushing down your transformation to HANA

2. Only go for HANA when dealing with data intensive processing having poor performance

3. Consider only converting those ABAP routines to HANA-based routine if:


a. You want to address key performance loading issues
b. To enable the business to move from daily to hourly loads as an example.

4. Consider the complexity involved for the conversion, the required skill sets, experience and timeframe.
HANA Pushdown via AMDP is a new change of mindset specially if you are used to ABAP application
programming. You need to develop your SQL skills in this area and as I mentioned, you need to find a way
how you can convert complex ABAP routines into SQL when possible

5. Make sure you have enough data to simulate in the Development Environment - enough data to satisfy your
test scenarios

Based on my experience, it’s very difficult to prove your AMDP work in an environment with a very limited
test data. You’ll end up coming up with multiple transports to another environment which has enough data
and this becomes messy in terms of deployment.

SAP HANA Based Transformation | 01.20.2017 | Page 21


6. Appendix

6.1 Example #1

6.1.1 ABAP Routine


FORM compute_/BIC/ZSTORE
USING
RECORD_NO type sy-tabix
TRAN_STRUCTURE type _ty_s_SC_1__RULE_126
CHANGING
RESULT TYPE _ty_s_TG_1_full-/BIC/ZSTORE
RETURNCODE LIKE sy-subrc
ABORT LIKE sy-subrc
RAISING
cx_sy_arithmetic_error
cx_sy_conversion_error.

* DATA: l_s_errorlog TYPE rssm_s_errorlog_int.

Select single /BIC/ZRT_STORE into RESULT from /BIC/PZPA_SITE


where RT_CUSTPL = TRAN_STRUCTURE-RETAILSTOREID and /BIC/ZPA_SITE =
TRAN_STRUCTURE-PLANT and OBJVERS = 'A'.

if sy-subrc <> 0.
* Select single /BIC/ZRT_STORE into RESULT from /BIC/PZPA_SITE
* where RT_CUSTPL = TRAN_STRUCTURE-RETAILSTOREID and OBJVERS = 'A'.
Select /BIC/ZRT_STORE into RESULT up to 1 rows from /BIC/PZPA_SITE
where RT_CUSTPL = TRAN_STRUCTURE-RETAILSTOREID and OBJVERS = 'A'
order by rt_custpl /bic/zpa_site.
endselect.

endif.

* returncode <> 0 means skip this record


RETURNCODE = 0.
* abort <> 0 means skip whole data package !!!
ABORT = 0.

ENDFORM. "/BIC/ZSTORE

6.1.2 AMD Routine

SAP HANA Based Transformation | 01.20.2017 | Page 22


CLASS /BIC/00O2TJJG7QWKUMWNK746GKC3R IMPLEMENTATION.

METHOD PROCEDURE BY DATABASE PROCEDURE FOR HDB LANGUAGE SQLSCRIPT OPTIONS READ-ONLY USING
/BIC/PZPA_SITE.
-- INSERT YOUR CODING HERE

-- If there’s no data retail store + plant combination,


-- Fetch data where retail store + plant combination exists

LOOKUP = SELECT t1.RT_CUSTPL as RETAILSTOREID,


t1."/BIC/ZPA_SITE" as PLANT,
COALESCE (t1."/BIC/ZRT_STORE",'') as "/BIC/ZRT_STORE",
a.RECORD,
a.SQL__PROCEDURE__SOURCE__RECORD
FROM "/BIC/PZPA_SITE" as t1 INNER JOIN :INTAB as a
ON t1.RT_CUSTPL = a.RETAILSTOREID
AND t1."/BIC/ZPA_SITE" = a.PLANT
WHERE t1.OBJVERS = 'A'

UNION

-- fetch data using only retail store


SELECT RT_CUSTPL as RETAILSTOREID,
"/BIC/ZPA_SITE" as PLANT,
"/BIC/ZRT_STORE",
RECORD,
SQL__PROCEDURE__SOURCE__RECORD
FROM (SELECT a.RT_CUSTPL, a."/BIC/ZPA_SITE", a."/BIC/ZRT_STORE",
b.RECORD, b.SQL__PROCEDURE__SOURCE__RECORD,
RANK() OVER (PARTITION BY a.RT_CUSTPL ORDER BY a.RT_CUSTPL,
a."/BIC/ZPA_SITE", a."/BIC/ZRT_STORE") as Rank
FROM "/BIC/PZPA_SITE" as a INNER JOIN :INTAB as b
ON a.RT_CUSTPL = b.RETAILSTOREID
WHERE a.OBJVERS = 'A'
AND NOT EXISTS (SELECT "/BIC/ZRT_STORE" FROM "/BIC/PZPA_SITE"
WHERE RT_CUSTPL = b.RETAILSTOREID
AND "/BIC/ZPA_SITE" = b.PLANT)
ORDER BY a.RT_CUSTPL, a."/BIC/ZPA_SITE", a."/BIC/ZRT_STORE")
WHERE Rank = 1;

OUTTAB = SELECT COALESCE (b."/BIC/ZRT_STORE", '') as "/BIC/ZRT_STORE",


a.RECORD,
a.SQL__PROCEDURE__SOURCE__RECORD
FROM :INTAB as a LEFT OUTER JOIN :LOOKUP as b
ON a.RECORD = b.RECORD
AND a.SQL__PROCEDURE__SOURCE__RECORD = b.SQL__PROCEDURE__SOURCE__RECORD;

ERRORTAB = SELECT '' AS ERROR_TEXT, '' AS SQL__PROCEDURE__SOURCE__RECORD FROM DUMMY WHERE DUMMY <>
'X';

ENDMETHOD.
ENDCLASS.

6.2 Example #2

6.2.1 ABAP Routine


METHOD start_routine.
*=== Segments ===

FIELD-SYMBOLS:
<SOURCE_FIELDS> TYPE _ty_s_SC_1.

DATA:
MONITOR_REC TYPE rstmonitor.

DATA : wa_source_package TYPE _ty_s_sc_1.


DATA : t_source_package TYPE _ty_t_sc_1.
DATA : l_source_package TYPE _ty_t_sc_1.

SAP HANA Based Transformation | 01.20.2017 | Page 23


l_source_package[] = SOURCE_PACKAGE[].

data: lv_param type /BIC/OIZPARAM,


it_param type standard table of /BIC/PZPARAM,
wa_param like line of it_param,
lv_found type char1,
lv_commit type i,
lv_match type i,
lv_tabix type i.

refresh: it_param.
clear: lv_param,
wa_param.
* Get the InfoCube name

* Determine the paramater value to use


lv_param = 'ZASREC02_SALESORG%'.

* Get the parameter value to restrict the records that are to be loaded
select *
into table it_param
from /BIC/PZPARAM
where /BIC/ZPARAM LIKE lv_param and
OBJVERS = 'A'.
if sy-subrc <> 0.
* Assume US based InfoCubes/ODS
lv_param = 'AM_SALESORG%'.

select *
into table it_param
from /BIC/PZPARAM
where /BIC/ZPARAM LIKE lv_param and
OBJVERS = 'A'.
if sy-subrc <> 0.

exit.
endif.
endif.

* Loop at the data package and then the sales org parameters, if the
* sales org is not between the parameter values delete the record.
LOOP AT l_source_package INTO wa_SOURCE_PACKAGE.
clear: lv_found.
lv_tabix = sy-tabix.

loop at it_param
into wa_param.

if wa_SOURCE_PACKAGE-SALESORG >= wa_param-/BIC/ZPARAMVAL and


wa_SOURCE_PACKAGE-SALESORG <= wa_param-/BIC/ZPARAMTO.
lv_found = 'X'.
endif.
endloop.

* If the value is not found in the parameters delete the record


if lv_found <> ' '.
APPEND wa_source_package TO t_source_package.
endif.

ENDLOOP.

SOURCE_PACKAGE[] = t_SOURCE_PACKAGE[].

Delete SOURCE_PACKAGE where /BIC/ZRPA_VOID = 'X'.

SAP HANA Based Transformation | 01.20.2017 | Page 24


*** Delete l_source_package where /BIC/ZRPA_VOID = 'X'.

*$*$ end of routine - insert your code only before this line *-*

ENDMETHOD. "start_routine

6.2.2 AMDP Routine


METHOD PROCEDURE BY DATABASE PROCEDURE FOR HDB LANGUAGE SQLSCRIPT OPTIONS READ-
ONLY USING /BIC/PZPARAM.
Declare lv_param varchar(30);
Declare v_count int;

-- Determine the paramater value to use


lv_param := 'ZASREC02_SALESORG%';
select count(*) into v_count from "/BIC/PZPARAM"
where "/BIC/ZPARAM" LIKE lv_param and OBJVERS = 'A';

if v_count = 0 then
lv_param := 'AM_SALESORG%';
end if;

-- Get the parameter value to restrict the records that are to be loaded
it_param = select * from "/BIC/PZPARAM"
where "/BIC/ZPARAM" LIKE lv_param and OBJVERS = 'A';

select count(*) into v_count from :it_param;

if :v_count = 0 then
OUTTAB = SELECT * FROM :inTab Where a."/BIC/ZRPA_VOID" <> 'X';
else
-- Check recods from the sales org parameters, get only those salesorgs within the
parameter values
OUTTAB = select a.*
from :inTab as a
where exists (select b.*
from :it_param as b
where a.salesorg between b."/BIC/ZPARAMVAL"
and b."/BIC/ZPARAMTO")
and a."/BIC/ZRPA_VOID" <> 'X';
end if;

ERRORTAB = SELECT '' AS ERROR_TEXT, '' AS SQL__PROCEDURE__SOURCE__RECORD FROM


DUMMY WHERE DUMMY <> 'X';
ENDMETHOD.

6.3 Example #3

6.3.1 ABAP Routine


******* DATA DECLARATIONS OF START ROUTINE***************
** Break Out Records that Have Multiple coupons Applied
Data: Begin of ls_Coupon_Count,
RT_LOCATIO type /BI0/OIPLANT,
RPA_TNR type /BI0/OIRPA_TNR,
COUNT TYPE i,
end of ls_Coupon_Count.

Data: Begin of ls_Coupon_ID,


RT_LOCATIO type /BI0/OIPLANT,
RPA_TNR type /BI0/OIRPA_TNR,

SAP HANA Based Transformation | 01.20.2017 | Page 25


RPA_DID type /BI0/OIRPA_DID,
end of ls_Coupon_ID.

TYPES begin of ltype_Coupon_Count.


Include structure ls_Coupon_Count.
TYPES end of ltype_Coupon_Count.

TYPES begin of ltype_Coupon_ID.


Include structure ls_Coupon_ID.
TYPES end of ltype_Coupon_ID.

DATA: lt_COUPON_COUNT type standard table of ltype_Coupon_Count.


DATA: lt_COUPON_ID type standard table of ltype_Coupon_ID.

DATA: lt_NEW_RECORDS like SOURCE_PACKAGE.


DATA: ls_NEW_RECORDS like line of lt_NEW_RECORDS.

DATA: lv_COUPON_COUNT TYPE I.

***********************************************************
*Collect Coupon Count Per Transaction
LOOP AT SOURCE_PACKAGE ASSIGNING <SOURCE_FIELDS>.

IF <SOURCE_FIELDS>-RPA_DID <> ''.


LS_COUPON_COUNT-RPA_TNR = <SOURCE_FIELDS>-RPA_TNR.
LS_COUPON_COUNT-RT_LOCATIO = <SOURCE_FIELDS>-RT_LOCATIO.
LS_COUPON_COUNT-COUNT = 1.
COLLECT LS_COUPON_COUNT INTO LT_COUPON_COUNT.
LS_COUPON_ID-RPA_TNR = <SOURCE_FIELDS>-RPA_TNR.
LS_COUPON_ID-RPA_DID = <SOURCE_FIELDS>-RPA_DID.
LS_COUPON_ID-RT_LOCATIO = <SOURCE_FIELDS>-RT_LOCATIO.
COLLECT LS_COUPON_ID INTO LT_COUPON_ID.

ENDIF.

ENDLOOP.

LOOP AT SOURCE_PACKAGE ASSIGNING <SOURCE_FIELDS>.


READ TABLE LT_COUPON_COUNT INTO LS_COUPON_COUNT
WITH KEY RPA_TNR = <SOURCE_FIELDS>-RPA_TNR
RT_LOCATIO = <SOURCE_FIELDS>-RT_LOCATIO.
IF SY-SUBRC EQ 0. "There is one or more Coupon
lv_COUPON_COUNT = 1.
LOOP AT LT_COUPON_ID INTO LS_COUPON_ID
WHERE RPA_TNR = <SOURCE_FIELDS>-RPA_TNR
AND RT_LOCATIO = <SOURCE_FIELDS>-RT_LOCATIO.

MOVE-CORRESPONDING <SOURCE_FIELDS> TO LS_NEW_RECORDS.


LS_NEW_RECORDS-/BIC/ZRPA_DID = LS_COUPON_ID-RPA_DID.
LS_NEW_RECORDS-/BIC/ZRPA_FS = lv_COUPON_COUNT.
APPEND LS_NEW_RECORDS TO LT_NEW_RECORDS.
Add 1 to lv_COUPON_COUNT.
ENDLOOP.
ENDIF.
ENDLOOP.

*We have moved all of the Coupon records to a new table,


*so delete the old ones form the SOURCE_PACKAGE TABLE
LOOP AT LT_COUPON_COUNT INTO LS_COUPON_COUNT.
DELETE SOURCE_PACKAGE
WHERE RPA_TNR EQ LS_COUPON_COUNT-RPA_TNR
AND RT_LOCATIO EQ LS_COUPON_COUNT-RT_LOCATIO.

SAP HANA Based Transformation | 01.20.2017 | Page 26


ENDLOOP.

* Now Add the new records back to the SOURCE_PACKAGE Table


LOOP AT LT_NEW_RECORDS INTO LS_NEW_RECORDS.
APPEND LS_NEW_RECORDS TO SOURCE_PACKAGE.
ENDLOOP.

*$*$ end of routine - insert your code only before this line *-*
ENDMETHOD. "start_routine

6.3.2 AMDP Routine


METHOD PROCEDURE BY DATABASE PROCEDURE FOR HDB LANGUAGE SQLSCRIPT OPTIONS
READ-ONLY.
-- Generate sequence numbers for transactions with multiple coupons
COUPONCNT = Select a.RPA_TNR, a."/BIC/ZRT_STORE", a.RPA_DID,
rank() Over (Partition by a.RPA_TNR,
a."/BIC/ZRT_STORE"
order by a.RPA_TNR, a."/BIC/ZRT_STORE",
a.RPA_DID) as "/BIC/ZRPA_FS"
from :INTAB as a
Where a.RPA_DID <> ''
order by a.RPA_TNR, a."/BIC/ZRT_STORE", a.RPA_DID;

-- Update the output table with the new sequence number


OUTTAB = Select a."/BIC/ZRT_STORE",
a."/BIC/ZRPA_TNR",
a.RPA_DID,
b."/BIC/ZRPA_FS",
a.RECORD,
a.SQL__PROCEDURE__SOURCE__RECORD
From :INTAB as a
Left outer join : COUPONCNT as b
On a.RPA_TNR = b.RPA_TNR
And a."/BIC/ZRT_STORE" = b."/BIC/ZRT_STORE"
And a.RPA_DID = a.RPA_DID;

ERRORTAB = SELECT '' AS ERROR_TEXT, '' AS SQL__PROCEDURE__SOURCE__RECORD


FROM DUMMY WHERE DUMMY <> 'X';
ENDMETHOD.
ENDCLASS.

6.4 Example #4

6.4.1 ABAP Routine


ABAP Field-Routine

data:
t_price TYPE /BI0/OIPRICE_AVG,
t_month TYPE /BI0/OICALMONTH,
t_year TYPE /BI0/OICALYEAR.

SELECT MAX( CALMONTH ) PRICE_AVG


INTO (t_month, t_price)
from /BIC/AGIMXXP0300
WHERE MATERIAL = SOURCE_FIELDS-MATERIAL
and PLANT = SOURCE_FIELDS-PLANT
and VAL_TYPE = SOURCE_FIELDS-VAL_TYPE

SAP HANA Based Transformation | 01.20.2017 | Page 27


and AF_GRDVAL = SOURCE_FIELDS-AF_GRDVAL
and CALMONTH <= SOURCE_FIELDS-CALMONTH
GROUP BY PRICE_AVG.
ENDSELECT.

RESULT = t_price.

6.4.2 AMDP Routine

METHOD PROCEDURE BY DATABASE PROCEDURE FOR HDB LANGUAGE SQLSCRIPT OPTIONS READ-ONLY USING
/BIC/AGIMXXP0300.
-- INSERT YOUR CODING HERE

Tab1 = SELECT a.material, a.plant, a.val_type, a.af_grdval,


a.RECORD, a.SQL__PROCEDURE__SOURCE__RECORD,
a.price_avg, b.calmonth as calmonth
FROM :inTab AS a
INNER JOIN "/BIC/AGIMXXP0300" as b
ON a.material = b.material
AND a.plant = b.plant
AND a.val_type = b.val_type
AND a.af_grdval = b.af_grdval
ORDER BY a.material, a.plant, a.val_type, a.af_grdval,
a.RECORD, a.SQL__PROCEDURE__SOURCE__RECORD, a.price_avg
WHERE b.calmonth <= a.calmonth;

Tab2 = SELECT material, plant, val_type, af_grdval,


RECORD, SQL__PROCEDURE__SOURCE__RECORD,
price_avg, calmonth,
Rank() over (Partition by material, plant, val_type, af_grdval, RECORD,
SQL__PROCEDURE__SOURCE__RECORD, order by material, plant, val_type, af_grdval, RECORD,
SQL__PROCEDURE__SOURCE__RECORD, price_avg, calmonth) as row_id
FROM :Tab1;

Tab3 = SELECT material, plant, val_type, af_grdval, RECORD, SQL__PROCEDURE__SOURCE__RECORD,


Max(row_id) as row_id
FROM :Tab2
GROUP BY material, plant, val_type, af_grdval, RECORD, SQL__PROCEDURE__SOURCE__RECORD;

Tab4 = SELECT DISTINCT a.PRICE_AVG, a.RECORD, a.SQL__PROCEDURE__SOURCE__RECORD


FROM :Tab2 as a INNER JOIN :Tab3 as b
ON a.RECORD = b.RECORD
AND a.SQL__PROCEDURE__SOURCE__RECORD = b.SQL__PROCEDURE__SOURCE__RECORD
AND a.row_id = b.row_id

OUTTAB = SELECT COALESCE(b.PRICE_AVG,0) as PRICE_AVG,


a.RECORD,
a.SQL__PROCEDURE__SOURCE__RECORD
FROM :INTAB as a LEFT OUTER JOIN :Tab4 as b
ON a.RECORD = b.RECORD
AND a.SQL__PROCEDURE__SOURCE__RECORD = b.SQL__PROCEDURE__SOURCE__RECORD;

ERRORTAB = SELECT '' AS ERROR_TEXT, '' AS SQL__PROCEDURE__SOURCE__RECORD FROM DUMMY WHERE DUMMY <>
'X';

ENDMETHOD.

SAP HANA Based Transformation | 01.20.2017 | Page 28

You might also like