外部系统调用SAP RFC接口取数,如果数据量太大,有时候会导致外部系统无法处理,所以希望能够分批取回数据,比如一次5万条。
这种接口有多个写法,有的是每次调用都重新取数,然后根据对方传入的起始和结束行把数据摘出来返回去,有的是把取出来的数据存到表,每次把表里的数据发出去指定条目数,并在表里删除这部分数据,还有的是在SQL中就使用分页功能,正所谓小鸡不尿尿,各有各的道儿,但是这些方法都不怎么好用,有这种那种的问题。数据是不断在更新的,如果不在一个时间点把数据取完,有可能会造成数据的不一致。
今天分享一个利用RFC的特性做的分批次传输数据接口,这种方式是效率最高且数据最正确的接口方式。
前提知识:SAP在调用函数的时候,会把整个函数组都放入内存,并且函数的全局变量会一直保持到程序结束,在函数多次调用的时候,可以通过全局变量获取上次调用的状态,外部系统调用RFC函数的时候如果使用了长连接(会话保持),这个特性亦是如此,也就是说,外部系统一旦开始调用,函数的上下文会一直在内存中,除非主动断掉连接。
本方案就是利用了这一特性,数据取出来后放到一个全局内表,返回指定的条目数后,在全局内表删除这部分数据,如果删除后内表不为空则说明数据还没有返回完,则设置参数MORKZ为X,外部系统发现此参数为X后,知道还有数据,就会再一次调用,直到MORKZ为空。如果剩余的数据不想要了,直接断开会话即可。
如果是SAP产品通过RFC互相调用,默认就是会话保持连接,除非专门使用函数RFC_CONNECTION_CLOSE断开连接,
如果是JAVA调用SAP,使用 JCoContext.begin和 JCoContext.end来使会话保持连接。具体用法请根据这两个关键字搜索。
题外话:现在很多新人做数据同步接口只知道PI(PO)和WebService,问及RFC,则言技术太老已经过时了。这个观点是错误的,不论从哪点来说,RFC都是做接口的第一选择。
分页(分批)取数示例:
FUNCTION ztest_rfc_01.*"----------------------------------------------------------------------*"*"局部接口:*" IMPORTING*" VALUE(COUNT) TYPE I OPTIONAL*" EXPORTING*" VALUE(MORKZ) TYPE CHAR1*" TABLES*" T_MAKT STRUCTURE MAKT OPTIONAL*"---------------------------------------------------------------------- IF gt_makt[] IS INITIAL. SELECT * INTO TABLE gt_makt FROM makt. ENDIF.CLEAR t_makt[]. IF count IS INITIAL. t_makt[] = gt_makt[]. CLEAR gt_makt[]. ELSE. APPEND LINES OF gt_makt FROM 1 TO count TO t_makt . DELETE gt_makt FROM 1 TO count. ENDIF.
IF gt_makt IS NOT INITIAL. morkz = 'X'. ENDIF.ENDFUNCTION."TOP文件FUNCTION-POOL ZTEST02. "MESSAGE-ID .. DATA gt_makt type TABLE OF makt.