Quantcast
Channel: SCN : All Content - ABAP for SAP HANA
Viewing all articles
Browse latest Browse all 831

Converting ABAP SELECT-OPTIONS to SQL WHERE for HANA

$
0
0

Fetching data from HANA DB via ABAP, with secondary database connection, is playing key role in current circumstances. This will help happy end user, with amazing response time, to compare actual results against lot of existing R/3 reports. With this approach, they can still utilize power of SAP reporting tools like ABAP List Viewer.  

 

There are many ways to get data from HANA to ABAP program, but if you are using native SQL with help of series of classes/method that we have then you may want to compose native SQL query with WHERE condition based on the user inputs on ABAP selection screen. Something like,

 

....WHERE "BUKRS" = 'ABC'

 

This is very simple when input is 'PARAMETER' or single values entered in 'SELECT-OPTIONS'. How about below selection from field that declared with 'SELECT-OPTIONS'?

  • 10 single values (included)
  • Greater than one perticular value
  • Exclude couple of values
  • Include one range of values
  • Exclude one range of values

 

Not sure about business case , however this is something that can be possible with ABAP select query! Then how can we convert this into SQL when we run ABAP program on HANA DB?

 

In this blog, I am sharing logic that will help us to compose 'where' condition with input values of 'select-options'. In fact, we need similar kind of code snipets to fully utilize HANA specific SQL statements for ABAP, for example, FUZZY SEARCH. Building a library(may be a global class) with all these functions will help us to utilize power of HANA specific SQL. 

 

Now, coming back to original topic, create one global class and a method in it. Below listed should be signature of the method.

 

INPUT_CH is the importing table parameter with structure that has SIGN(CHAR1), OPTION(CHAR2) and LOW and HIGH(CHAR80). This should work for all data types including DATS, CURR etc.., We should pass ranges table (copy of select-options table) to this parameter.

SQL_FNAME is importing parameter with technical type CHAR40. We should pass hard coded HANA table field name to this parameter.

WHERE is changing parameter with technical type STRING. This will return WHERE condition, this can be used in SELECT query.

 

And the code is...

 

 data: wa_input_ch like line of input_ch.
 data: first,       where_local type string,       where_local_i type string,       where_local2 type string,       opr type char3,       sql_fname_q like sql_fname,       option type char8.  clear: opr, where_local, where_local2.

 * Prepare one internal variable with quotes (optional)
  sql_fname_q = '"' && sql_fname && '"'.

 * Loop through the ranges to get single or multiple values to be included
    clear first.  " This will help to format that data in correct order within below loop    loop at input_ch into wa_input_ch where ( sign = 'I' and option = 'EQ' ) or ( sign = 'E' and option = 'NE' ).      if first is initial. " For the first interation       first = 'X'. " Update this flag to modify code in next interation       where_local = where_local && sql_fname_q && ' IN ( ''' && wa_input_ch-low && ''''. " Formatting inputs in "IN (f1,f2,f3)" format       opr = 'OR'.  " This operator will help as separator for next set of search on same input range (not in this loop)      else.       where_local = where_local && ',' && '''' && wa_input_ch-low && ''''. " Seperating values with commas      endif.    endloop.    if sy-subrc = 0.  " If we have at least one record in above loop then we should close the search with "IN" operator     concatenate where_local ')' into where_local separated by space.    endif.
 * Single value(s) with NULL value - to be Included/We are using this code because in HANA view, 
* we will have 'space' and '?' for
 * empty values depends on mapping. To cover both, we had to add below logic in addition to above. 
* This applies to single value & NULL value search only
 * Here we are using hard coded "OR" because it will be always "OR" as we are already searching with SPACE in above LOOP    loop at input_ch into wa_input_ch where ( ( sign = 'I' and option = 'EQ' ) or ( sign = 'E' and option = 'NE' ) ) and low is initial.      concatenate where_local 'OR (' sql_fname_q 'IS NULL )' into where_local separated by space.    endloop.

 * One or More than one range to be included - When we have single or multiple values;
* Using Operator "OR" based on opr variable or it can be space
    loop at input_ch into wa_input_ch where ( sign = 'I' and option = 'BT' ) or ( sign = 'E' and option = 'NB' ).      where_local2 = sql_fname_q && ' BETWEEN ''' && wa_input_ch-low && ''' AND ''' && wa_input_ch-high && ''''.      concatenate where_local opr '(' where_local2 ')' into where_local separated by space.      if opr is initial.       opr = 'OR'.  " This will be helpfull for next interation of same LOOP      endif.      clear where_local2.    endloop.
 * LT and other operators including CP    loop at input_ch into wa_input_ch where sign = 'I' and        ( option = 'LT' or option = 'GT' or option = 'LE' or option = 'GE' or option = 'CP' ).      case wa_input_ch-option.       when 'LT'.         option = '<'.       when 'GT'.         option = '>'.       when 'LE'.         option = '<='.       when 'GE'.         option = '>='.       when 'CP'.         option = 'LIKE'.         replace '*' in wa_input_ch-low with '%'.      endcase.      concatenate sql_fname_q option '''' into where_local2 separated by space.      where_local2 = where_local2 && wa_input_ch-low && ''''.      concatenate where_local opr '(' where_local2 ')' into where_local separated by space.      if opr is initial.       opr = 'OR'.  " This will be helpfull for next interation of same LOOP      endif.      clear: option, where_local2.    endloop.

 * Windup everything in one bracket before searching for EXCLUDING

  if where_local is not initial.     concatenate '(' where_local ')' into where_local separated by space.     where_local_i = where_local. " Store WHERE condition one temparary variable to have it in seperate brackets     clear where_local.
 *    if opr is not initial.  " Value "OR" should not be there for next loop
 *     opr = 'AND'.
 *    endif.    endif.    clear opr.
 * Loop through the ranges to get single or multiple values to be excluded;
 * We are using opr operator in below as opr can have value in it from first loop. If not then it will be space as exepcted    clear first.  " This will help to format that data in correct order within below loop    loop at input_ch into wa_input_ch where ( sign = 'I' and option = 'NE' ) or ( sign = 'E' and option = 'EQ' ).      if first is initial." For the first interation       first = 'X'." Update this flag to modify code in next iteration       where_local = where_local && sql_fname_q && ' NOT IN ( ''' && wa_input_ch-low && ''''.       opr = 'AND'." This operator will help as separator for next set of search on same input range (not in this loop)      else.       where_local = where_local && ',' && '''' && wa_input_ch-low && ''''.      endif.    endloop.    if sy-subrc = 0.  " If we have at least one record in above loop then we should close the search with "IN" operator     concatenate where_local ')' into where_local separated by space.    endif.

 * Single value(s) with NULL value - to be Included/We are using this code because in HANA view, 
*we will have 'space' and '?' for
 * empty values depends on mapping. TO cover both, we had to add below logic in addition to above.
* This applies to single value & NULL value search only
 * Here we are using hard coded "AND" because it will be always "AND" as 
*we are already searching with SPACE in above LOOP    loop at input_ch into wa_input_ch where ( ( sign = 'I' and option = 'NE' ) or ( sign = 'E' and option = 'EQ' ) ) and low is initial.      concatenate where_local 'AND (' sql_fname_q 'IS NOT NULL )' into where_local separated by space.      opr = 'AND'.    endloop.

 * One or More than one range to be excluded - When we have single or multiple values
    loop at input_ch into wa_input_ch where ( sign = 'E' and option = 'BT' ) or ( sign = 'I' and option = 'NB' ).      where_local2 = sql_fname_q && ' NOT BETWEEN ''' && wa_input_ch-low && ''' AND ''' && wa_input_ch-high && ''''.      concatenate where_local opr '(' where_local2 ')' into where_local separated by space.       if opr is initial.        opr = 'AND'.       endif.      clear where_local2.    endloop.
 * LT and other operaters    loop at input_ch into wa_input_ch where sign = 'E' and 
( option = 'LT' or option = 'GT' or option = 'LE' or option = 'GE' or option = 'CP' ).      case wa_input_ch-option.       when 'LT'.         option = '>='.       when 'GT'.         option = '<='.       when 'LE'.         option = '>'.       when 'GE'.         option = '<'.       when 'CP'.         option = 'NOT LIKE'.         replace '*' in wa_input_ch-low with '%'.      endcase.      concatenate sql_fname_q option '''' into where_local2 separated by space.      where_local2 = where_local2 && wa_input_ch-low && ''''.      concatenate where_local opr '(' where_local2 ')' into where_local separated by space.      if opr is initial.       opr = 'AND'.  " This will be helpfull for next interation of same LOOP      endif.      clear: option, where_local2.    endloop.   if where_local_i is not initial.    if where_local is not initial.     concatenate where_local_i 'AND (' where_local ')' into where_local separated by space.    else.     where_local = where_local_i.    endif.   endif.   read table input_ch into wa_input_ch index 1.    if sy-subrc = 0.     concatenate where 'AND (' where_local ')' into where separated by space.    endif.

 

You can call this method multiple times to extend 'where' condition with other select-options. This logic/method will not work for parameter as we are accepting ranges as input, however, we can declare 'select-options' with no extension and no intervals and pass it to above method.

 

Finally, we should use below piece of code to get final statement.

   if where is not initial.      where = where+4.      concatenate 'WHERE' where into where separated by space.   endif.

 

Now, all we need to do is, use above 'WHERE' variable in SELECT query while passing statement to HANA via CL_SQL_STATEMENT->EXECUTE_QUERY

 

You can try fuzzy search something like below. This is very simple code that triggers Fuzzy Search for ABAP Selection Screen 'Parameter' field. You can increase or decrease fuzzy rate 0.7 as suggested in HANA guide.

 

  WHERE = 'CONTAINS (' && <field name in HANA view> && ', ''' && <input value from ABAP program> && ''',' && 'FUZZY(0.7))'.

 

 

 

Thanks,

Naveen Inuganti


Viewing all articles
Browse latest Browse all 831

Trending Articles