Skip to content

ABAP Keyword Documentation →  ABAP − Reference →  Processing External Data →  ABAP Database Access →  ABAP and SAP HANA →  ABAP and SAP HANA, Examples 

SAP HANA, from ADBC to AMDP

This example demonstrates how a task can be performed using HANA-specific language elements.

Other versions: 7.31 | 7.40 | 7.54

Source Code

    DATA(out) = cl_demo_output=>new( ).

    IF NOT cl_abap_dbfeatures=>use_features(
          EXPORTING
            requested_features =
              VALUE #( ( cl_abap_dbfeatures=>call_database_procedure )
                       ( cl_abap_dbfeatures=>call_amdp_method ) ) ).
      cl_demo_output=>display(
      `Current database system does not support all procedure calls` ).
      RETURN.
    ENDIF.

    DATA carrier TYPE spfli-carrid VALUE 'LH'.
    cl_demo_input=>request( CHANGING field = carrier ).
    DATA(oref) = NEW cl_demo_from_adbc_to_amdp( to_upper( carrier ) ).

    DATA(osql_result) = oref->osql( ).
    DATA(adbc_result) = oref->adbc( ).
    DATA(cdbp_result) = oref->cdbp( ).
    DATA(amdp_result) = oref->amdp( ).

    IF osql_result = adbc_result AND
       osql_result = cdbp_result AND
       osql_result = amdp_result.
      out->begin_section(
        `Result of Open SQL, ADBC, CALL DATABASE PROCEDURE, and AMDP`
        )->write( amdp_result ).
    ELSE.
      out->write( 'Error' ).
    ENDIF.
    out->display( ).

Description

The task is to read all rows from the database table SFLIGHTS whose key fields MANDT, CARRID, and CONNID occur in a predefined three-column internal table. To do this, the example program calls various methods of the class CL_DEMO_FROM_ADBC_TO_AMDP in whose instance constructor the internal table connection_tab is filled in accordance with user input.


Note

The examples of using HANA-specific language elements shown in the methods are syntax-only examples. The task presented here can be solved just as well using ABAP SQL, which is why ABAP SQL is the preferred method as specified in the programming guidelines.

Reference Implementation Using ABAP SQL

The method OSQL shows how the task can be solved in ABAP SQL by simply using the addition FOR ALL ENTRIES. The result of the method is used as a reference for the HANA-specific implementations.

METHOD osql.
  IF connection_tab IS NOT INITIAL.
    SELECT *
          FROM sflight
          FOR ALL ENTRIES IN @connection_tab
          WHERE carrid = @connection_tab-carrid AND
                connid = @connection_tab-connid
          INTO TABLE @flights.
  ENDIF.
ENDMETHOD.

Using Native SQL with ADBC

The method ADBC solves the task using HANA-specific Native SQL statements passed to the SAP HANA database using ADBC. The table with the key values is evaluated after the addition exists in a subquery of a select statement. To do this, a temporary table DEMO_ADBC_CONNECTIONS is created on the database and filled with the content of the connection_tab using the statement insert. To access the result of the select statement, a standard table std_flights must be declared as a local internal table of the method, since the return value flights cannot be used for ADBC. The temporary table DEMO_ADBC_CONNECTIONS is removed again after SPFLI is read.

METHOD adbc.
  DATA(sql) = NEW cl_sql_statement( ).

  TRY.
      sql->execute_update( 'truncate table DEMO_ADBC_CONNECTIONS' ).
      sql->execute_ddl(    'drop table DEMO_ADBC_CONNECTIONS' ).
    CATCH cx_sql_exception ##no_handler.
  ENDTRY.

  TRY.
      sql->execute_ddl(
        `create global temporary row table DEMO_ADBC_CONNECTIONS ` &&
        `( MANDT  NVARCHAR(3), `                                   &&
          `CARRID NVARCHAR(3), `                                   &&
          `CONNID NVARCHAR(4) )` ).

      sql->set_param_table( REF #( connection_tab ) ).
      sql->execute_update(
        `insert into DEMO_ADBC_CONNECTIONS values ( ?, ?, ? )` ).

      DATA(result) = sql->execute_query(
        `    select * `                                   &&
        `      from SFLIGHT as S `                        &&
        `      where exists (`                            &&
        `        select MANDT, CARRID, CONNID `           &&
        `               from  DEMO_ADBC_CONNECTIONS as C` &&
        `               where C.MANDT  = S.MANDT and `    &&
        `                     C.CARRID = S.CARRID and `   &&
        `                     C.CONNID = S.CONNID )` ).
      DATA std_flights TYPE STANDARD TABLE OF sflight WITH EMPTY KEY.
      result->set_param_table( REF #( std_flights ) ).
      result->next_package( ).
      result->close( ).
      flights = std_flights.

      sql->execute_update( 'truncate table DEMO_ADBC_CONNECTIONS' ).
      sql->execute_ddl( '   drop table DEMO_ADBC_CONNECTIONS' ).

    CATCH cx_sql_exception.
      CLEAR flights.
  ENDTRY.
ENDMETHOD.

Call a Database Procedure Using a Database Procedure Proxy

The method CDBP solves the task by implementing the HANA-specific select statement in a database procedure called by specifying a database procedure proxy in the statement CALL DATABASE PROCEDURE. In a more realistic example, the database procedure DEMO_ADBC_GET_FLIGHTS and the database procedure proxy DEMO_ADBC_GET_FLIGHTS_PROXY would already exist and the implementation of the method would be restricted to the call CALL DATABASE PROCEDURE (compare with the executable example for procedure calls). In this example, the database procedure and the database procedure proxy are created temporarily using ADBC methods and the associated API, then deleted again. The input parameter connections of the procedure references an additional temporary HANA table type, DEMO_ADBC_CONNECTIONS_TYPE. HANA does not support a separate type for numeric text, which means that the type NVARCHAR(4) must be used for the column CONNID. Also, the internal table connection_tab must be assigned to a temporary table connections with the correct row type before the procedure is called. No auxiliary table is required for the result, since the row type is described using an ABAP Dictionary type. An appropriate mapping can be performed for this type using the mapping table params. As an alternative to an auxiliary table for connection_tab, its data type could be declared in ABAP Dictionary too and an appropriate mapping performed.

METHOD cdbp.
  DATA(sql) = NEW cl_sql_statement( ).

  TRY.
      sql->execute_ddl( 'drop type DEMO_ADBC_CONNECTIONS_TYPE' ).
    CATCH cx_sql_exception ##no_handler.
  ENDTRY.
  TRY.
      sql->execute_ddl( `drop procedure DEMO_ADBC_GET_FLIGHTS` ).
    CATCH cx_sql_exception ##no_handler.
  ENDTRY.

  TRY.
      sql->execute_ddl(
        `create type DEMO_ADBC_CONNECTIONS_TYPE as table ` &&
        `( MANDT  NVARCHAR(3), `                           &&
          `CARRID NVARCHAR(3), `                           &&
          `CONNID NVARCHAR(4) )` ).
      sql->execute_ddl(
        `create procedure DEMO_ADBC_GET_FLIGHTS  `            &&
        `  ( in CONNECTIONS DEMO_ADBC_CONNECTIONS_TYPE,  `    &&
        `    out FLIGHTS SFLIGHT ) language sqlscript as `    &&
        `      begin `                                        &&
        `        FLIGHTS = `                                  &&
        `          select * `                                 &&
        `            from SFLIGHT as S `                      &&
        `            where exists (  `                        &&
        `              select MANDT, CARRID, CONNID `         &&
        `                     from :CONNECTIONS as C`         &&
        `                     where C.MANDT  = S.MANDT and `  &&
        `                           C.CARRID = S.CARRID and ` &&
        `                           C.CONNID = S.CONNID );`   &&
        `      end` ).


      DATA db_schema TYPE if_dbproc_proxy_basic_types=>ty_db_name.
      CALL FUNCTION 'DB_DBSCHEMA_CURRENT'
        IMPORTING dbschema = db_schema.

      DATA(params) =
        VALUE if_dbproc_proxy_basic_types=>ty_param_override_t(
        ( db_name   = 'FLIGHTS'
          abap_name = 'FLIGHTS'
          descr     = cl_abap_typedescr=>describe_by_name(
                      'SFLIGHT' ) ) ).

      DATA(api) = cl_dbproc_proxy_factory=>get_proxy_public_api(
        if_proxy_name = 'DEMO_ADBC_GET_FLIGHTS_PROXY' ).
      api->delete( ).
      api->create_proxy( EXPORTING
                  if_proc_schema    = db_schema
                  it_param_override = params
                  if_proc_name      = 'DEMO_ADBC_GET_FLIGHTS' ).
      COMMIT CONNECTION default.

      TYPES:
        BEGIN OF connection,
          mandt  TYPE c LENGTH 3,
          carrid TYPE c LENGTH 3,
          connid TYPE c LENGTH 4,
        END OF connection.
      DATA connections TYPE STANDARD TABLE OF connection
                       WITH EMPTY KEY.
      connections = connection_tab.

      CALL DATABASE PROCEDURE ('DEMO_ADBC_GET_FLIGHTS_PROXY')
        EXPORTING connections = connections
        IMPORTING flights     = flights.

      COMMIT CONNECTION default.
      api->delete( ).
      sql->execute_ddl( `drop procedure DEMO_ADBC_GET_FLIGHTS` ).
      sql->execute_ddl( 'drop type DEMO_ADBC_CONNECTIONS_TYPE' ).
    CATCH cx_sql_exception cx_dbproc_proxy.
      CLEAR flights.
  ENDTRY.

ENDMETHOD.

Call an AMDP Procedure

The method AMDP solves the task in the easiest possible way by calling an AMDP method AMDP_METH in which the HANA-specific select statement is implemented in an AMDP procedure. The main advantage of the AMDP method is that it can be called in the same way as any ABAP method, without the need to implement any auxiliary tables (as in the preceding examples).

Method was not found