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: 

Transfer tables between 2 clients (mandants)

Former Member
0 Kudos

Hi every one.

I want to transfer data i have in some tables from client (mandant) 305 to another another to create an environnement of test with real data so we can test new programs in real conditions.

For the moment here's what i did :

I used RFC on just one table. And this works.

BUT the problem is that to work, we need to declare the table in the parameters of the function.

So Is there any way to avoid that declaration ? Because i have like 500 tables to transfer, and i 'm sure there's a better way than mine to do that. But as i just started on SAP and ABAP, can't figure it out.

My solution for the moment will the same but with a loop on all the tables i need to trasfer the data ... but i'll have to decalare the 500 tables in the parameters of my function :s

Maybe there's another solution to communicate between mandants so if you have, ideas, documentation, links etc, it will be really helpful

thx a lot !


REPORT ZTESTHDAFUNC .

DATA : t_ZVOITSUPOFF LIKE ZVOITSUPOFF OCCURS 0 WITH HEADER LINE.

CALL FUNCTION 'ZTESTHDAFUNC' DESTINATION 'DO2_305'
  TABLES ZVOITSUPOFF  = t_ZVOITSUPOFF.
CALL FUNCTION 'ZTESTHDAFUNCW'
 TABLES ZVOITSUPOFF  = t_ZVOITSUPOFF.

CALL FUNCTION 'ZTESTHDAINSERT'
 TABLES ZVOITSUPOFF = t_ZVOITSUPOFF.


FUNCTION ZTESTHDAFUNC.
select *
  from ZVOITSUPOFF
  into table ZVOITSUPOFF
  WHERE ZIDENT_CANAL = 'FFR'.


ENDFUNCTION.

FUNCTION ZTESTHDAINSERT.
LOOP AT ZVOITSUPOFF.
  INSERT INTO ZVOITSUPOFF VALUES ZVOITSUPOFF.
ENDLOOP.

ENDFUNCTION.

25 REPLIES 25

Former Member
0 Kudos

Hi

I think you don't need to create a new function to do it, you can use the std fm RFC_READ_TABLE.

You can do it something like this:

DATA: T_OPTIONS LIKE STANDARD TABLE OF RFC_DB_OPT,

T_FIELDS LIKE STANDARD TABLE OF RFC_DB_FLD,

T_DATA LIKE STANDARD TABLE OF TAB512 WITH HEADER LINE.

DATA: WA TYPE REF TO DATA.

DATA: BEGIN OF MY_TABLES OCCURS 1,

TABNAME LIKE DD02L-TABNAME,

END OF MY_TABLES.

FIELD-SYMBOLS: <WA> TYPE ANY.

LOOP AT MY_TABLES.

CREATE DATA WA TYPE (MY_TABLES-TABNAME).

ASSIGN WA->* TO <WA>.

CALL FUNCTION 'RFC_READ_TABLE' DESTINATION ....

EXPORTING

QUERY_TABLE = MY_TABLES-TABNAME

  • DELIMITER = ' '

  • NO_DATA = ' '

  • ROWSKIPS = 0

  • ROWCOUNT = 0

TABLES

OPTIONS = T_OPTIONS

FIELDS = T_FIELDS

DATA = T_DATA

  • EXCEPTIONS

  • TABLE_NOT_AVAILABLE = 1

  • TABLE_WITHOUT_DATA = 2

  • OPTION_NOT_VALID = 3

  • FIELD_NOT_VALID = 4

  • NOT_AUTHORIZED = 5

  • DATA_BUFFER_EXCEEDED = 6

  • OTHERS = 7

.

IF SY-SUBRC <> 0.

  • MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO

  • WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.

ENDIF.

LOOP AT T_DATA.

MOVE T_DATA TO <WA>.

UPDATE (MY_TABLES-TABNAME) FROM <WA>.

ENDLOOP.

ENDLOOP.

Max

Message was edited by: max bianchi

0 Kudos

Thanx for your answers.

At the moment i'm trying the solution max gave me but there's a few things i don't understand.

I tried the solution in debbug mode but the table MY_TABLES is never filled with the informations from DD02L. Is it normal ?

By the way how works the table T_OPTIONS ? It's int his one where we specify wich tables we will work on but how ? Do we use a query ?

For example if i only whant tables starting by ztest*, how do i do that in te T_OPTIONS ?

0 Kudos

Hi

Yes it is, because you aren't finding the information about your tables.

In your problem I did seem you didn't need to know that informations, but you did need to know only the data.

The function RFC_READ_TABLE should be get out those informations.

In T_OPTIONS you can define your WHERE conditions for the queries, but it's not easy to say how, because it depend on the table you have to read.

IF you want to read all tables with name starting ZTES* (but without to pass WHERE conditions):

SELECT TABNAME FROM DD02L INTO TABLE MY_TABLES

WHERE TABNAME LIKE 'ZTEST%'

AND ASLOCAL = 'A'.

LOOP AT MY_TABLES.

CREATE DATA WA TYPE (MY_TABLES-TABNAME).

ASSIGN WA->* TO <WA>.

CALL FUNCTION 'RFC_READ_TABLE' DESTINATION ....

EXPORTING

QUERY_TABLE = MY_TABLES-TABNAME

  • DELIMITER = ' '

  • NO_DATA = ' '

  • ROWSKIPS = 0

  • ROWCOUNT = 0

TABLES

OPTIONS = T_OPTIONS

FIELDS = T_FIELDS

DATA = T_DATA

  • EXCEPTIONS

  • TABLE_NOT_AVAILABLE = 1

  • TABLE_WITHOUT_DATA = 2

  • OPTION_NOT_VALID = 3

  • FIELD_NOT_VALID = 4

  • NOT_AUTHORIZED = 5

  • DATA_BUFFER_EXCEEDED = 6

  • OTHERS = 7

.

IF SY-SUBRC <> 0.

  • MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO

  • WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.

ENDIF.

LOOP AT T_DATA.

MOVE T_DATA TO <WA>.

UPDATE (MY_TABLES-TABNAME) FROM <WA>.

ENDLOOP.

ENDLOOP.

In the table T_FIELDS you can see the informations about the table you're reading.

Max

Message was edited by: max bianchi

0 Kudos

Thanks Max for your help.

I think i'm near to the end but i still got one last problem.

I checked the table T_DATA, and it contains the information needed.

But when i enter the loop where i update the tables with the data i tranfered from another client, the update is never done !

SY-SUBRC is always equals to 4 and i don't understand why. Do i have to change the way we treat the data from T_DATA ?


  LOOP AT T_DATA.
    MOVE T_DATA TO <WA>.
    UPDATE (MY_TABLES-TABNAME) FROM <WA>.
    IF SY-SUBRC <> 0.
      MESSAGE e081 with text-016.
    ENDIF.
  ENDLOOP.

NB: by the way if anyone have to do the same thing one day, you may encounter an exception of DATA_BUFFER_EXCEEDED. To avoid that, create your own RFC_READ_TABLE and instead of using the structure TAB512 to read the table records, you can use one larger.

0 Kudos

Hi

I think the problem is UPDATE statament, if you use use this command, it means you want only to update your client, so if the record has to be updated isn't in the new client, your action'll fail.

Try to Use INSERT or MODIFY command.

If you have some problems on the length of the structure for data I believe you should create an your Z-RFC with DATA table with a field longer than 512 char.

Max

Message was edited by: max bianchi

0 Kudos

Hi Helder,

I am just wondering if that is because the record with the specified key doesn't exist in the Database table. I would rather suggest you to use Modify which acts as Update+Insert.

Hope this helps.

Regards,

Srikanth

0 Kudos

you need to use CLIENT SPECIFIED along with your update/modify/insert statements to be able to update target client table from source client.

Regards

Raja

0 Kudos

Yeah I'm sorry !

While using the debbug mode i just notice that the problem came from the 'update' ... I can't update something that doesn't exist yet in the table... :S

Hope this time it will not need anymore ! Thanks for the help and happy new year everyone

0 Kudos

Hi.

I still have some problems if anybody knows how I can handle it:

Every time i try to transfer a table wich contains prices i.e. DATA with the type CURR, I have an ERROR :

ABAPDBIF_RSQL_INVALID_REQUEST.

I if just try to print the data, evrething goes fine, so the problem really comes from the query. How can i modify the query to make it work also when i'm working with CURR ?


  LOOP AT T_DATA.
    MOVE T_DATA TO <WA>.
    INSERT (MY_TABLES-TABNAME) FROM <WA>.
    WRITE : / <WA>. "test print
  ENDLOOP.

0 Kudos

Hi,

Give your full code, ..

along with data declarations.

Thanks

vijay

0 Kudos

Hi

I think the problem is on the MOVE statament, if your table have currency fields, problably the positions of data on table T_DATA don't respect the structure of table, so you should find out the characteristics (offset, field length,...) of your table and use it to move the data correctly.

Max

0 Kudos

I use my own RFC_READ_TABLE where instead of TAB512, i use a larger table but still with CHAR.



REPORT ZTESTHDA3 MESSAGE-ID zvoi.
TABLES : DD02L.


DATA:BEGIN OF MY_TABLES OCCURS 1,
     TABNAME LIKE DD02L-TABNAME,
     END OF MY_TABLES.

DATA : T_OPTIONS LIKE STANDARD TABLE OF RFC_DB_OPT,
       T_FIELDS LIKE STANDARD TABLE OF RFC_DB_FLD,
       T_DATA LIKE STANDARD TABLE OF ZTAB8000 WITH HEADER LINE.


DATA : WA TYPE REF TO DATA.

FIELD-SYMBOLS : <WA> TYPE ANY.

PERFORM lecture_DD02L.

LOOP AT MY_TABLES.

  CREATE DATA WA TYPE (MY_TABLES-TABNAME).
  ASSIGN WA->* TO <WA>.
  CLEAR T_FIELDS.
  REFRESH T_DATA. 
  CLEAR T_DATA.


  CALL FUNCTION 'ZRFC_READ_TABLE' DESTINATION 'DO2_305'
    EXPORTING
    QUERY_TABLE = MY_TABLES-TABNAME
*    DELIMITER = ' '
*    NO_DATA = ' '
*    ROWSKIPS = 0
*    ROWSCOUNT = 0
    TABLES
      OPTIONS = T_OPTIONS
      FIELDS = T_FIELDS
      DATA = T_DATA
*     EXCEPTIONS
*     TABLE_NOT_AVAILABLE = 1
*     TABLE_WITHOUT_DATA = 2
*     OPTION_NOT_VALID = 3
*     FIELD_NOT_VALID = 4
*     NOT_AUTHORIZED = 5
*     DATA_BUFFER_EXCEEDED = 6   
*     OTHERS = 7
  . "fin appel ZRFC_READ_TABLE

  IF sy-subrc <> 0.
     MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO
     WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.
  ENDIF.


  LOOP AT T_DATA.
    MOVE T_DATA TO <WA>.
*    INSERT (MY_TABLES-TABNAME) FROM <WA>.
    WRITE : / <WA>. "pr test, permet de connaitre enreg lu
  ENDLOOP.

ENDLOOP.

FORM lecture_DD02L.
  SELECT TABNAME
  FROM DD02L
  INTO TABLE MY_TABLES
  WHERE TABNAME LIKE 'ZVOITPRITAR' " test date et monnaie
  AND TABCLASS LIKE 'TRANSP' 
  AND AS4LOCAL = 'A'. 

    IF sy-subrc <> 0.
      MESSAGE e081 WITH text-013.
    ENDIF.

ENDFORM.                    " lecture_DD02L


0 Kudos

Hi Helder,

This error should supposedly happen when the table has currency or decimal fields. Can you please confirm this?

Regards,

Srikanth

0 Kudos

Hi

try to use a code like this

DATA: tab_info LIKE STANDARD TABLE OF dfies WITH HEADER LINE.

DATA tabname TYPE ddobjname.

DATA: string TYPE string.

FIELD-SYMBOLS: <wa>, <value>.

CALL FUNCTION 'DDIF_FIELDINFO_GET'

EXPORTING

tabname = tabname

  • FIELDNAME = ' '

  • LANGU = SY-LANGU

  • LFIELDNAME = ' '

  • ALL_TYPES = ' '

  • GROUP_NAMES = ' '

  • UCLEN =

  • IMPORTING

  • X030L_WA =

  • DDOBJTYPE =

  • DFIES_WA =

  • LINES_DESCR =

TABLES

dfies_tab = tab_info

  • FIXED_VALUES =

  • EXCEPTIONS

  • NOT_FOUND = 1

  • INTERNAL_ERROR = 2

  • OTHERS = 3

.

IF sy-subrc <> 0.

  • MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO

  • WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.

ENDIF.

LOOP AT tab_info.

ASSIGN COMPONENT tab_info-fieldname OF STRUCTURE <wa> TO <value>.

MOVE string+tab_info-offset(tab_info-intlen) TO <value>.

ENDLOOP.

Max

0 Kudos

Hi Max,

We are exactly there where I was giving the two options(please refer to the very first reply I gave). The reason why I am trying to highlight this is not to show anyone wrong but trying to tell you the implications.

If the number of records are more and so the number of fields, the number of iterations the loop takes is high as well. And trust me I have personally seen how painful is it with performance. It degrades it a lot. I still say the option 2 would be a better approach to this problem

Regards,

Srikanth

former_member188685
Active Contributor
0 Kudos

Hi,

Generate table maintenance and transport all the entries of the table from one server to another server.

regards

vijay

Former Member
0 Kudos

Hi Halder,

I have come across a similar issue like the one which you had explained. In RFC FMs, the tables parameter must be typed and cannot be untyped. We had two approaches to choose.

a) Use a unstructured internal table of length around 20000 characters and send the values as per their fixed lengths. Say if I am sending data of table 'A' and it has three fields

one 10 in length

two 20 in length

three 30 in length

Then in the character field I send data with fixed positions as value of field one starts from 1 and ends at 10, value of field two starts at 11 and ends at 30 and so on.

This gave us a performance issue as decoding the fields was a major task. Then we chose to use option b.

b) We listed all the tables which we use for this RFC FM maintained it in a table and transported it to the other system as well. Then we added a parameter called tablename to the FM and created dynamic internal table using:

DATA:

tref TYPE REF TO data.

CREATE DATA tref TYPE STANDARD TABLE OF (tablename).

Used dynamic selects to fill in the data and used it in the calling clients. Let me know in case you need any furhter info on this.

Regards,

Srikanth

0 Kudos

Hi Srikanth,

Could you please give me more information about your option b) because there’s a few points i’m not sure to understand :

So in the first step you created a table wich contains all the table’s name we want to transfer. Is that it ? What else did you put in the table you created ?

Then you transfer this table into the other client ?

Could you please show me how you managed to solve this problem ?

In my case, performance is not a priority, but i think it will be veray painful if i have to handle the types ..

Thanks.

0 Kudos

Hi Helder,

Let me explain you the implication whatz gonna happen if you use the following loop.

LOOP AT tab_info.

ASSIGN COMPONENT tab_info-fieldname OF STRUCTURE <wa> TO <value>.

MOVE string+tab_info-offset(tab_info-intlen) TO <value>.

ENDLOOP.

Say if I have 20 fields in my table with 2000 records, for this one table, the processor would loop for 40000 times. Which is surely pretty huge time.

Now coming to option b), it is pretty simpler. The table which I was referring is not required as we created it for a specific requirement.

List all the tables which you need for data transfer. Let us assume here as we had done and we came up with two. They are:

ZTESTA

ZTESTB

The function module has the following interface parameters:

FUNCTION zrfc_read_table.

IMPORTING

tabname TYPE dd02l-tabname

TABLES

t_ztesta

t_ztestb.

All that you do in your FM is:

FIELD-SYMBOLS: <fs_table> TYPE STANDARD TABLE.

DATA: l_inttab TYPE char64.

CONCATENATE 'T_'

tabname

INTO l_inttab.

ASSIGN (l_inttab) TO <fs_table>

SELECT * FROM (tabname) INTO TABLE <fs_table>.

ENDFUNCTION.

Now in your original program:

*After selecting all the tables you want(here in this case

*you would have only ZTESTA and ZTESTB in MY_TABLES)

TYPE-POOLS: abap.

DATA : table TYPE REF TO data,

WA TYPE REF TO DATA,

it_param TYPE STANDARD TABLE OF

abap_func_parmbind,

wa_param TYPE abap_func_parmbind.

FIELD-SYMBOLS : <FS> TYPE STANDARD TABLE,

<WA> TYPE ANY.

LOOP AT MY_TABLES.

CREATE DATA table TYPE STANDARD TABLE OF

(MY_TABLES-TABNAME).

CREATE DATA WA TYPE (MY_TABLES-TABNAME).

ASSIGN WA->* TO <WA>.

ASSIGN TABLE->* TO <fs>

  • Pass the interface parameters dynamically using

  • it_parm which is of type abap_func_parmbind(4.7) or

  • abap_parmbind(4.6c) in type-pools abap.(I am not sure if

  • we can do it in a version less than 4.7). Let me know

  • in case you dont know how to pass interface parameters

  • to a function module dynamically.

CALL FUNCTION 'ZRFC_READ_TABLE' DESTINATION 'DO2_305'

PARAMETER-TABLE

it_parm.

IF sy-subrc <> 0.

MESSAGE ID SY-MSGID TYPE SY-MSGTY NUMBER SY-MSGNO

WITH SY-MSGV1 SY-MSGV2 SY-MSGV3 SY-MSGV4.

ENDIF.

LOOP AT <fs> INTO <wa>.

INSERT (MY_TABLES-TABNAME) FROM <WA>.

ENDLOOP.

ENDLOOP.

Here you need not have to loop no. of rows * no.of columns. Also your FM is quicker as it is just one select statement and do not do anything else.

All that you need to do is to identify all the tables and add tables parameters as t_<tabname>. But the code nover change.

Regards,

Srikanth

0 Kudos

Hi Srikanth,

There’s a few things strange in the code you gave me yesterday.

I’ve got 2 errors :

-> On the instruction

-> CREATE DATA table TYPE STANDARD TABLE OF (MY_TABLES-TABNAME).

I’ve got this in result : UNABLE TO INTERPRET "TABLE". Possibles causes of error: Incorrect spelling or comma error.

-> On : CALL FUNCTION 'ZRFC_LECT_TABLE' DESTINATION 'DO2_305'

PARAMETER-TABLE it_parm.

Same thing but with "PARAMETER-TABLE". Can’t interpret that and when I check the options for CALL FUNCTION, in my system (4.6C) I don’t have PARAMETER-TABLE. Maybe It’s only available from 4.7 and above.

Do you have an idea to correct that ?

And by the way, it will be helpful you can explain how to pass interface parameters

to a function module dynamically . I’m sorry to bother you but I just started learning ABAP so there’s still a lot of things that I have to discover

Regards.

0 Kudos

Hi Helder,

I realised that we will not be able to pass interface parameters dynamically to function module for versions 4.6c and below. I have worked on it in the version 4.7.

Also, the following statement is allowed in 4.7 version where I have used it but seems to be not working in 4.6c.

These two have come as a learning to me as well.

CREATE DATA table TYPE STANDARD TABLE OF (MY_TABLES-TABNAME).

Anyways I will let you know about other options we have in version 4.6c in case we will be able to accomodate it.

Regards,

Srikanth

athavanraja
Active Contributor
0 Kudos

if your objective is to move data from one client to another client (wtihin the same application server) then you can do like explained below.

source clinet '001'

target client '002' .

in 002 write a program with the following statement.

select * from <dbtablename> CLIENT SPECIFIED into table itab1 where mandt = '001'

and you can add other where conditions as well.

Hope this helps.

Regards

Raja

Message was edited by: Durairaj Athavan Raja

0 Kudos

if you are on WAS6.20 and above and wanted a enhanced RFC_READ_TABLE checkout this code sample.

https://www.sdn.sap.com/irj/servlet/prt/portal/prtroot/docs/library/uuid/f50dcd4e-0501-0010-3596-b68...

Regards

Raja

Former Member
0 Kudos

Yes that's it : the error happens when i try to use a table with decimal fields or currency.

Former Member
0 Kudos

Helder,

In order to transfer data from one client to another, you don't need any program. Create a new request in source client. Lock the table entries in the request by manually adding them (use wild character if possible)at task. Then use <b>transaction SCC1 in target client</b> ( with checkbox checked on for 'include task'). The table entries will be transferred.

I hope it helps.