Application Development Discussions
Join the discussions or start your own on all things application development, including tools and APIs, programming models, and keeping your skills sharp.
cancel
Showing results for 
Search instead for 
Did you mean: 

Call RFC Function Module and return 1000 records at a time

aaron_morden2
Contributor
0 Kudos

I would like to call a Remote Enabled Function Module from a non SAP system. This function module will select data from the database and return it to the calling program.

Suppose there are 100,000 records that need to be returned, but the calling module would like the data in chunks of 1000 records. Therefore the calling program would call the FM 100 times.

How do I code the function module to know on each subsequent call to grab the next chunk of 1000 records?

Let me know if additional information is needed.

Thanks,

Aaron

1 ACCEPTED SOLUTION

former_member218674
Contributor
0 Kudos

Hello,

Here is how you can go for this issue:

1. Create one RFC function module with following parameter. These parameters are with respective of chunking logic.

Import: Package Size

Export: Total number of records

Changing: chunk count

Implement following logic:

1. First of you need to know how many chunks you need to fetch for that get the count of total number of records. This is one

time activity so you better maintain one flag import parameter will be set to 'X' only first call.

2. Get the number of chunk using total number of records / chunk size for e.g. 1000 / 100 so chunk count = 10.

3. Define internal chunk counter in function module which will be used to locate the correct chunk depending on the chunk

counter value sent from calling program.

4. Send first call with package size 100 and chunk count = 1, execute select statement and increment internal

chunk count check if chunk count = internal chunk count in current case chunk count = 1 so exit select statement and return

with first chunk.

5. Send second call with package size 100 and chunk count = 2. Execute select statement and check chunk count with internal

chunk counter, in current case it will be 1 so skip that data and go for next chunk of 100 records increment internal chunk

counter. In this case it will match with external chunk count = 2. load output table with that data and return to calling program.

6. Repeat step 4 until you reach last chunk.

You need to use SELECT...ENDSELECT with PACKAGE SIZE addition so for every loop it will return number of records mentioned in package size.

Hope this helps.

Thanks,

Augustin.

8 REPLIES 8

Former Member
0 Kudos

hai ,

for that u can pass a paramter which will count the call ,

for each call increase the count from ur call and based on that igonre the records which earlier returned

for example if coutn is 1 then ignore first 1000 records and fetch next 1000

for this u have to fetch the data completely in internal table each time and process the internal tables looping with the index

m.a

0 Kudos

So my Select statement will need to select 100,000 records for each call? Is this the only option or are there other options?

0 Kudos

Hi

Yes I think so, the problem it can keep the select waiting for the next reading, so every time it need to skip the record just elaborated in the previous selection.

This is a code I used to read the data of a table in BW from R3:

*"----------------------------------------------------------------------
*"*"Interfaccia locale:
*"  IMPORTING
*"     VALUE(DATUM) TYPE  SY-DATUM
*"     VALUE(TIMES) TYPE  SY-UZEIT
*"     VALUE(MAX_RECORD) TYPE  I OPTIONAL
*"     VALUE(FROM_RECORD) TYPE  I OPTIONAL
*"     VALUE(PACKAGE_SIZE) TYPE  I DEFAULT 20000
*"  EXPORTING
*"     VALUE(LAST_RECORD) TYPE  I
*"     VALUE(CLOSE_READING) TYPE  FLAG
*"  TABLES
*"      T_RPRO_MOV_IN STRUCTURE  ZRPRO_MOV_IN_RFC
*"----------------------------------------------------------------------
* Verifica dimensione pacchetti
  IF PACKAGE_SIZE IS INITIAL.
    EXIT.
  ENDIF.
* Inizializzazione parametri

* Calcolo timestamp
  CONVERT DATE DATUM TIME TIMES INTO
     TIME STAMP _TIME TIME ZONE SY-ZONLO.


* Contatori
  _TOT_REC   = 0.
  _APPE_IDX  = 0.

*
  _STOP         = SPACE.
  CLOSE_READING = SPACE.

* Apertura lettura tabella
  IF _TIME IS INITIAL.
    OPEN CURSOR _DBCURSOR
     FOR SELECT * FROM /BIC/AZODSMOVI00.
  ELSE.
    OPEN CURSOR _DBCURSOR
     FOR SELECT * FROM /BIC/AZODSMOVI00 WHERE TCTLSTLOAD > _TIME.
  ENDIF.
  IF SY-SUBRC <> 0.
* Fine lettura
    CLOSE_READING = 'X'.
    EXIT.
  ENDIF..

Max

0 Kudos

Step 2

DO.
    FETCH NEXT CURSOR _DBCURSOR
      INTO TABLE T_AZODSMOVI00 PACKAGE SIZE PACKAGE_SIZE.
    IF SY-SUBRC <> 0.
* Fine lettura
      CLOSE_READING = 'X'.
      EXIT.
    ENDIF.
* Verifica totale record estratti
    DESCRIBE TABLE T_AZODSMOVI00 LINES _PACKAGE.
    _TOT_REC = _TOT_REC + _PACKAGE.

    IF _TOT_REC > FROM_RECORD.
* Ultimo pacchetto
      _LAST_PC = _TOT_REC - _PACKAGE.

* Se ultimo record pacchetto precedente, coincide o supreriore con
* punto di partenza => leggo tabella intera
      IF _LAST_PC => FROM_RECORD.
        _READ_IDX = 0.
      ELSE.
        _READ_IDX = FROM_RECORD - _LAST_PC.
      ENDIF.

* Si inizia lettura se totale record estratte superiore ad ultimo record estratto
      DO.
        _READ_IDX = _READ_IDX  + 1.
        READ TABLE T_AZODSMOVI00 INTO /BIC/AZODSMOVI00 INDEX _READ_IDX.
        IF SY-SUBRC <> 0. EXIT. ENDIF.
* Aggiorno indice numero record da appendere
        _APPE_IDX = _APPE_IDX + 1.

* Se raggiunto max record esportabili blocco ciclo
        IF _APPE_IDX > MAX_RECORD AND MAX_RECORD > 0.
          _STOP = 'X'.
          EXIT.
        ENDIF.

Max

Edited by: max bianchi on Jul 21, 2009 4:30 PM

0 Kudos

Step 3

* Caricamento dati
       MOVE ..................................
        APPEND T_RPRO_MOV_IN.
        LAST_RECORD = FROM_RECORD + _APPE_IDX.
      ENDDO.
      IF _STOP = 'X'. EXIT. ENDIF.
    ENDIF.
  ENDDO.
* Chiusura lettura
  CLOSE CURSOR _DBCURSOR.
ENDFUNCTION

Sorry, but the description are in italian

Max

0 Kudos

Max,

I have question for you please.

If the table in which making a fetch DONOT have a time stamp field, then

0 Kudos

Hi

?

I've used the field TIMESTAMP just to export the record inserted or changed from last time the RFC run. Here I don't need to read all records, but only the new or updated one.

Max

former_member218674
Contributor
0 Kudos

Hello,

Here is how you can go for this issue:

1. Create one RFC function module with following parameter. These parameters are with respective of chunking logic.

Import: Package Size

Export: Total number of records

Changing: chunk count

Implement following logic:

1. First of you need to know how many chunks you need to fetch for that get the count of total number of records. This is one

time activity so you better maintain one flag import parameter will be set to 'X' only first call.

2. Get the number of chunk using total number of records / chunk size for e.g. 1000 / 100 so chunk count = 10.

3. Define internal chunk counter in function module which will be used to locate the correct chunk depending on the chunk

counter value sent from calling program.

4. Send first call with package size 100 and chunk count = 1, execute select statement and increment internal

chunk count check if chunk count = internal chunk count in current case chunk count = 1 so exit select statement and return

with first chunk.

5. Send second call with package size 100 and chunk count = 2. Execute select statement and check chunk count with internal

chunk counter, in current case it will be 1 so skip that data and go for next chunk of 100 records increment internal chunk

counter. In this case it will match with external chunk count = 2. load output table with that data and return to calling program.

6. Repeat step 4 until you reach last chunk.

You need to use SELECT...ENDSELECT with PACKAGE SIZE addition so for every loop it will return number of records mentioned in package size.

Hope this helps.

Thanks,

Augustin.