Skip to Content
Technical Articles
Author's profile photo Andre Fischer

Using long string in function imports

Motivation

Recently I got a question in SCN where a SCN user had problems with sending long strings using a function import.

So I created a SEGW project in both the latest stack as well as in 740 (the latest SP though) to check whether I would be able to reproduce the issue.

I wasn’t able to do so but wanted to share in detail how it worked for me.

I will work on publishing this and other code on Github but for the time being I just post screen shots and source code

SEGW Project

I created a project ZAF_SAMPLE_001 with an entity type SalesOrderDescription and an EntitySet SalesOrderDescription as follows:

soid is of type Edm.String , length 10

description is of type Edm.String, length 1000

Both field names were chosen automatically since the entity type is not bound to a DDIC structure.

Then I created a function import SetDescription with two parameters Salesorder (Edm.String with a length of 10) and Description (Edm.String with a length 1000).

The ABAP Field Names ZAF_SAMPLE_001_DESCRIPTION and ZAF_SAMPLE_001_SALESORDER are NOT existing DDIC types but the names were just chosen randomly when creating the function import parameters.

Table

The data was stored in a simple table whose fields are using the ABAP internal types CHAR(30) and CHAR(1000).

@EndUserText.label : 'long descriptions'
@AbapCatalog.enhancementCategory : #NOT_EXTENSIBLE
@AbapCatalog.tableCategory : #TRANSPARENT
@AbapCatalog.deliveryClass : #A
@AbapCatalog.dataMaintenance : #LIMITED
define table zaf_sample_001 {
  key client  : abap.clnt not null;
  key soid    : abap.char(10) not null;
  description : abap.char(1000);

}

Result

When posting the following URI I got a response where all characters (more than 400 are being returned)

/sap/opu/odata/SAP/ZAF_SAMPLE_001_SRV/SetDescription?Salesorder='29'&Description='100 characters: '0123456789'0123456789'0123456789'0123456789'0123456789'0123456789'0123456789'0123456789'0123456789'0123456789'0123456789 200 characters: '0123456789'0123456789'0123456789'0123456789'0123456789'0123456789'0123456789'0123456789'0123456789'0123456789'0123456789 300 characters: '0123456789'0123456789'0123456789'0123456789'0123456789'0123456789'0123456789'0123456789'0123456789'0123456789'0123456789 400 characters: '0123456789'0123456789'0123456789'0123456789'0123456789'0123456789'0123456789'0123456789'0123456789'0123456789'0123456789'

DPC_EXT class (740)

Here is the code of the DPC_EXT class for 740 where no inline declaration of variables is allowed an no “@” must be used to mark parameters in SQL statements as host variables.

class ZCL_ZAF_SAMPLE_001_DPC_EXT definition
  public
  inheriting from ZCL_ZAF_SAMPLE_001_DPC
  create public .

  PUBLIC SECTION.
    METHODS /iwbep/if_mgw_appl_srv_runtime~execute_action
        REDEFINITION .
  PROTECTED SECTION.
    METHODS salesorderdescri_get_entity REDEFINITION.
    METHODS salesorderdescri_get_entityset REDEFINITION.
private section.
ENDCLASS.



CLASS ZCL_ZAF_SAMPLE_001_DPC_EXT IMPLEMENTATION.
  METHOD salesorderdescri_get_entityset.
    DATA: lv_osql_where_clause TYPE string,
          lv_top               TYPE i,
          lv_skip              TYPE i,
          lv_max_index         TYPE i,
          n                    TYPE i.
*- get number of records requested
    lv_top = io_tech_request_context->get_top( ).
*- get number of lines that should be skipped
    lv_skip = io_tech_request_context->get_skip( ).
*- value for maxrows must only be calculated if the request also contains a $top
    IF lv_top IS NOT INITIAL.
      lv_max_index = lv_top + lv_skip.
    ENDIF.
    lv_osql_where_clause = io_tech_request_context->get_osql_where_clause( ).

    SELECT * FROM zaf_sample_001
      INTO CORRESPONDING FIELDS OF TABLE et_entityset
      UP TO lv_max_index ROWS
      WHERE (lv_osql_where_clause).
*- skipping entries specified by $skip
    IF lv_skip IS NOT INITIAL.
      DELETE et_entityset TO lv_skip.
    ENDIF.
*-  Inlinecount - get the total numbers of entries that fit to the where clause
    IF io_tech_request_context->has_inlinecount( ) = abap_true.
      SELECT COUNT(*)  FROM   zaf_sample_001 WHERE (lv_osql_where_clause) .
      es_response_context-inlinecount = sy-dbcnt.
    ELSE.
      CLEAR es_response_context-inlinecount.
    ENDIF.

  ENDMETHOD.

  METHOD salesorderdescri_get_entity.
    DATA: lt_keys       TYPE /iwbep/t_mgw_tech_pairs,
          ls_key        TYPE /iwbep/s_mgw_tech_pair,
          ls_bp_key     TYPE zcl_zaf_sample_001_mpc=>ts_salesorderdescription-soid,
          ls_headerdata TYPE zcl_zaf_sample_001_mpc=>ts_salesorderdescription.

    CALL METHOD io_tech_request_context->get_converted_keys
      IMPORTING
        es_key_values = ls_headerdata.

    ls_bp_key = ls_headerdata-soid.

    SELECT SINGLE *
      INTO CORRESPONDING FIELDS OF er_entity
      FROM zaf_sample_001
      WHERE soid = ls_headerdata-soid.
  ENDMETHOD.

  METHOD /iwbep/if_mgw_appl_srv_runtime~execute_action.



    DATA: ls_message           TYPE          scx_t100key.

    TYPES: BEGIN OF lty_import_parameter,
             ZAF_SAMPLE_001_SALESORDER  TYPE zaf_sample_001-soid,
             ZAF_SAMPLE_001_DESCRIPTION TYPE zaf_sample_001-description,
           END OF lty_import_parameter.
    DATA: ls_parameter_values     TYPE lty_import_parameter,

          lv_function_import_name TYPE /iwbep/mgw_tech_name.
    DATA ls_sales_description TYPE  zaf_sample_001.  " zcl_zaf_sample_001_mpc=>ts_salesorderdescription.
    DATA lt_sales_description TYPE STANDARD TABLE OF zaf_sample_001. "zcl_zaf_sample_001_mpc=>tt_salesorderdescription.


    lv_function_import_name = io_tech_request_context->get_function_import_name( ).

    io_tech_request_context->get_converted_parameters(
      IMPORTING
        es_parameter_values = ls_parameter_values ).

    CASE lv_function_import_name.

      WHEN 'SetDescription'.

        ls_sales_description-description = ls_parameter_values-ZAF_SAMPLE_001_description.
        ls_sales_description-soid = ls_parameter_values-ZAF_SAMPLE_001_salesorder.
        APPEND ls_sales_description TO lt_sales_description.
*
        INSERT zaf_sample_001 FROM TABLE lt_sales_description.
"        INSERT zaf_sample_001 FROM @ls_sales_description.
        " add check whether salesorder exist or not
        IF sy-subrc <> 0.
          " implement suitable error handling here
          ls_message-msgid = 'SY'.
          ls_message-msgno = '002'.
          CONCATENATE 'Update for ' ls_parameter_values-ZAF_SAMPLE_001_SalesOrder ' failed' INTO ls_message-attr1.

          RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception
            EXPORTING
              textid = ls_message.
*        ELSE.
*          ls_snwd_lock-node_key = ls_so-node_key.
        ENDIF.



data ls_entity type zcl_zaf_sample_001_mpc=>ts_salesorderdescription.


        SELECT SINGLE * FROM zaf_sample_001 INTO CORRESPONDING FIELDS OF ls_entity WHERE soid = ls_parameter_values-ZAF_SAMPLE_001_salesorder.

        IF ls_entity IS INITIAL.
          ls_message-msgid = 'SY'.
          ls_message-msgno = '002'.
          ls_message-attr1 = 'sales order not found'.

          RAISE EXCEPTION TYPE /iwbep/cx_mgw_busi_exception
            EXPORTING
              textid = ls_message.
        ENDIF.

        copy_data_to_ref( EXPORTING
        is_data = ls_entity CHANGING
        cr_data = er_data
        ).


    ENDCASE.
  ENDMETHOD.
ENDCLASS.

 

MPC code

Extract from the definition part of the MPC class

class ZCL_ZAF_SAMPLE_001_MPC definition
  public
  inheriting from /IWBEP/CL_MGW_PUSH_ABS_MODEL
  create public .

public section.

  types:
    begin of TS_SETDESCRIPTION,
        ZAF_SAMPLE_001_DESCRIPTION type C length 1000,
        ZAF_SAMPLE_001_SALESORDER type C length 10,
    end of TS_SETDESCRIPTION .

DEFINE_ACTIONS

  method DEFINE_ACTIONS.
*&---------------------------------------------------------------------*
*&           Generated code for the MODEL PROVIDER BASE CLASS         &*
*&                                                                     &*
*&  !!!NEVER MODIFY THIS CLASS. IN CASE YOU WANT TO CHANGE THE MODEL  &*
*&        DO THIS IN THE MODEL PROVIDER SUBCLASS!!!                   &*
*&                                                                     &*
*&---------------------------------------------------------------------*


data:
lo_action         type ref to /iwbep/if_mgw_odata_action,                 "#EC NEEDED
lo_parameter      type ref to /iwbep/if_mgw_odata_parameter.              "#EC NEEDED

***********************************************************************************************************************************
*   ACTION - SetDescription
***********************************************************************************************************************************

lo_action = model->create_action( 'SetDescription' ).  "#EC NOTEXT
*Set return entity type
lo_action->set_return_entity_type( 'SalesOrderDescription' ). "#EC NOTEXT
*Set HTTP method GET or POST
lo_action->set_http_method( 'POST' ). "#EC NOTEXT
*Set the action for entity
lo_action->set_action_for( 'SalesOrderDescription' ).        "#EC NOTEXT
* Set return type multiplicity
lo_action->set_return_multiplicity( '1' ). "#EC NOTEXT
***********************************************************************************************************************************
* Parameters
***********************************************************************************************************************************

lo_parameter = lo_action->create_input_parameter( iv_parameter_name = 'Description'    iv_abap_fieldname = 'ZAF_SAMPLE_001_DESCRIPTION' ). "#EC NOTEXT
lo_parameter->/iwbep/if_mgw_odata_property~set_type_edm_string( ).
lo_parameter->set_maxlength( iv_max_length = 1000 ). "#EC NOTEXT
lo_parameter = lo_action->create_input_parameter( iv_parameter_name = 'Salesorder'    iv_abap_fieldname = 'ZAF_SAMPLE_001_SALESORDER' ). "#EC NOTEXT
lo_parameter->/iwbep/if_mgw_odata_property~set_type_edm_string( ).
lo_parameter->set_maxlength( iv_max_length = 10 ). "#EC NOTEXT
lo_action->bind_input_structure( iv_structure_name  = 'ZCL_ZAF_SAMPLE_001_MPC=>TS_SETDESCRIPTION' ). "#EC NOTEXT
  endmethod.

 

Assigned Tags

      6 Comments
      You must be Logged on to comment or reply to a post.
      Author's profile photo Andy Pataselano
      Andy Pataselano

      Hi Andre,

      Thank you for nice blog.

      How about SAP Gateway license for SAP Business Suite named user license, need additional license or not?

      Best regards,

      Andy

      Author's profile photo Andre Fischer
      Andre Fischer
      Blog Post Author

      Since this question is not related to this blog can you please post it in the Q&A section.

      Author's profile photo Andy Pataselano
      Andy Pataselano

      Sorry, I already posted my question in the Q&A section. I hope you can help me, thank you.

      Author's profile photo Andre Fischer
      Andre Fischer
      Blog Post Author

      No problem. Gregor Wolf already answered this and I confirmed it.

      Author's profile photo Rodrigo Jordao
      Rodrigo Jordao

      Hello,

      The trouble I see with long strings, is that function import parameters are passed in the query string of the POST request, and query strings could have a limit imposed by the server (does Netweaver impose a limit?) or the client browser.

      So ideally, I would like to pass the long string in the body of the request. Is that possible?

      BTW I'm also currently using RAP and not gateway (no DPC_EXT or MPC_EXT).

      Author's profile photo Raymond Mannion
      Raymond Mannion

      Thank you for documenting this - I think I also saw your comment about using a length of 0 to indicate usage of STRING.

      The issue I ran into that was immensely frustrating was having to rename the ABAP field in order to really regenerate the definitions/declarations. Editing a data model entity type definition doesn't seem to invoke the same behavior as when you generate/create it from scratch.

      For example, my field was called ShipComments and even though I changed it to a length of 0, I still received the blessed "violates facet information" error.

      After I renamed the ABAP field name from SHIP_COMMENTS to SHIP_COMMENTS_STRING, I guess it forced something to be regenerated.

      Anyway - this was the best article on the subject, so I thought I would share this in case it helps someone..