YCL_SO5_ADBC
CLASS ycl_so5_adbc DEFINITION
PUBLIC
FINAL
CREATE PUBLIC .
PUBLIC SECTION.
METHODS constructor
IMPORTING
!iv_db_connection_name TYPE dbcon-con_name OPTIONAL
RAISING
ycx_so5_adbc .
METHODS select_into_table
IMPORTING
!iv_sql_query TYPE string OPTIONAL
!iv_db_name TYPE string OPTIONAL
!it_column_tab TYPE adbc_column_tab OPTIONAL
!ir_screen_fields TYPE REF TO data OPTIONAL
CHANGING
!ct_output_table TYPE STANDARD TABLE
RAISING
ycx_so5_adbc .
PROTECTED SECTION.
PRIVATE SECTION.
DATA mv_connection_name TYPE dbcon-con_name .
DATA mr_sql_connection TYPE REF TO cl_sql_connection .
DATA mr_sql_statement TYPE REF TO cl_sql_statement .
DATA mr_sql_result_set TYPE REF TO cl_sql_result_set .
DATA mr_cx_sql_exception TYPE REF TO cx_sql_exception .
DATA mr_cx_parameter_invalid TYPE REF TO cx_parameter_invalid .
DATA mt_cols TYPE adbc_column_tab .
ENDCLASS.
CLASS ycl_so5_adbc IMPLEMENTATION.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method YCL_SO5_ADBC->CONSTRUCTOR
* +-------------------------------------------------------------------------------------------------+
* | [--->] IV_DB_CONNECTION_NAME TYPE DBCON-CON_NAME(optional)
* | [!CX!] YCX_SO5_ADBC
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD constructor.
*== set the current apqp database
me->mv_connection_name = iv_db_connection_name.
*== create a connection object representing the default connection.
TRY .
me->mr_sql_connection = cl_sql_connection=>get_connection( me->mv_connection_name ).
*== create a statement object
me->mr_sql_statement = me->mr_sql_connection->create_statement( ).
CATCH cx_sql_exception INTO me->mr_cx_sql_exception.
* MESSAGE lr_exc TYPE 'I' DISPLAY LIKE 'E'. "--> Transaction SM21 = display SysLog
RAISE EXCEPTION TYPE ycx_so5_adbc
EXPORTING
textid = ycx_so5_adbc=>unknown_connection
object = CONV string( me->mv_connection_name )
class = cl_abap_classdescr=>get_class_name( me )
method = 'CONSTRUCTOR'.
ENDTRY.
ENDMETHOD.
* <SIGNATURE>---------------------------------------------------------------------------------------+
* | Instance Public Method YCL_SO5_ADBC->SELECT_INTO_TABLE
* +-------------------------------------------------------------------------------------------------+
* | [--->] IV_SQL_QUERY TYPE STRING(optional)
* | [--->] IV_DB_NAME TYPE STRING(optional)
* | [--->] IT_COLUMN_TAB TYPE ADBC_COLUMN_TAB(optional)
* | [--->] IR_SCREEN_FIELDS TYPE REF TO DATA(optional)
* | [<-->] CT_OUTPUT_TABLE TYPE STANDARD TABLE
* | [!CX!] YCX_SO5_ADBC
* +--------------------------------------------------------------------------------------</SIGNATURE>
METHOD select_into_table.
DATA: lv_tab_view TYPE string,
lv_sql_message TYPE string,
lv_splitter TYPE string,
lv_and_clause TYPE string,
bool_search_found TYPE abap_bool VALUE abap_true,
bool_first_component TYPE abap_bool.
DATA: lr_datatype TYPE REF TO cl_abap_datadescr.
*== break point
BREAK-POINT ID zbreak_test.
TRY .
IF ir_screen_fields IS NOT INITIAL.
*== build the needed SQL Query
DATA(lv_sql_query) =
|SELECT * FROM | && iv_db_name.
*-- get all components which are not initial and add where | and condition to the sql query{
ASSIGN ir_screen_fields->* TO FIELD-SYMBOL(<fs_screen_fields>).
DATA(lr_type_descr) = cl_abap_typedescr=>describe_by_data( <fs_screen_fields> ).
DATA lr_rowtype TYPE REF TO cl_abap_structdescr.
lr_rowtype ?= lr_type_descr.
LOOP AT lr_rowtype->get_components( ) ASSIGNING FIELD-SYMBOL(<fs_comp>).
ASSIGN COMPONENT sy-tabix OF STRUCTURE <fs_screen_fields>
TO FIELD-SYMBOL(<fs_field>).
IF <fs_field> IS NOT INITIAL.
*-- if we start with the first component add where condition
* after where --> add and condition
IF bool_first_component = abap_true.
lv_and_clause = ' AND'.
ELSE.
lv_and_clause = ' WHERE '.
bool_first_component = abap_true.
ENDIF.
lr_datatype ?= cl_abap_typedescr=>describe_by_data_ref( <fs_field> ).
CASE lr_datatype->type_kind.
WHEN 'C'.
ASSIGN <fs_field>->* TO FIELD-SYMBOL(<fs_to_string>).
SHIFT <fs_to_string> LEFT DELETING LEADING '0'.
IF <fs_to_string> CP '*#*'.
REPLACE ALL OCCURRENCES OF '*' IN <fs_to_string> WITH '%'.
lv_sql_query =
lv_sql_query && lv_and_clause && | | && <fs_comp>-name && | like | && |'| && <fs_to_string> && |'|.
ELSE.
lv_sql_query =
lv_sql_query && lv_and_clause && | | && <fs_comp>-name && | = | && |'| && <fs_to_string> && |'|.
ENDIF.
WHEN 'h'.
ASSIGN <fs_field>->* TO FIELD-SYMBOL(<fs_to_tab>).
DATA(lr_cond) = cl_lib_seltab=>new( it_sel = <fs_to_tab> ).
DATA(lv_cond) = lr_cond->sql_where_condition( <fs_comp>-name ).
lv_sql_query =
lv_sql_query && lv_and_clause && lv_cond.
ENDCASE.
ENDIF.
ENDLOOP.
*-- get all components which are not initial and add where | and condition to the sql query}
ELSE.
lv_sql_query = iv_sql_query.
ENDIF.
*== execute the query
me->mr_sql_result_set = me->mr_sql_statement->execute_query( lv_sql_query ).
*== set output table
IF it_column_tab IS INITIAL.
me->mr_sql_result_set->set_param_table( REF #( ct_output_table ) ).
ELSE.
me->mr_sql_result_set->set_param_table( itab_ref = REF #( ct_output_table )
corresponding_fields = it_column_tab ).
ENDIF.
*== get the complete result set
IF me->mr_sql_result_set->next_package( ) > 0.
* EXIT.
ENDIF.
*== close db connection
me->mr_sql_result_set->close( ).
CATCH cx_sql_exception INTO me->mr_cx_sql_exception.
* MESSAGE lr_exc TYPE 'I' DISPLAY LIKE 'E'. "--> Transaction SM21 = display SysLog
CASE mr_cx_sql_exception->sql_code.
WHEN 942.
SPLIT iv_sql_query AT 'FROM ' INTO lv_splitter lv_tab_view.
SPLIT lv_tab_view AT 'WHERE' INTO lv_tab_view lv_splitter.
SPLIT lv_tab_view AT 'ORDER' INTO lv_tab_view lv_splitter.
DATA(lv_error_string) = 'No authorization table/view:'(001) && ' ' && lv_tab_view.
WHEN OTHERS.
lv_sql_message = mr_cx_sql_exception->sql_message.
WHILE bool_search_found = abap_true.
SEARCH lv_sql_message FOR ':'.
IF sy-subrc = 0.
SPLIT lv_sql_message AT ': ' INTO lv_splitter lv_sql_message.
lv_error_string = lv_sql_message.
ELSE.
bool_search_found = abap_false.
lv_error_string = lv_sql_message.
ENDIF.
ENDWHILE.
ENDCASE.
RAISE EXCEPTION TYPE ycx_so5_adbc
EXPORTING
textid = ycx_so5_adbc=>sql_exception
key = CONV string( mr_cx_sql_exception->sql_code )
object = CONV string( lv_error_string )
class = cl_abap_classdescr=>get_class_name( me )
method = 'SELECT_INTO_TABLE'.
CATCH cx_parameter_invalid INTO me->mr_cx_parameter_invalid.
RAISE EXCEPTION TYPE ycx_so5_adbc
EXPORTING
textid = ycx_so5_adbc=>parameter_invalid
key = me->mr_cx_parameter_invalid->parameter && ' ' && 'not available'(002) "SPACE wurde mit ALT+255 plaziert
object = 'SQL QUERY'
class = cl_abap_classdescr=>get_class_name( me )
method = 'SELECT_INTO_TABLE'.
ENDTRY.
ENDMETHOD.
ENDCLASS.