BW中自定义数据源的Delta机制

来源:互联网 发布:镜面蛋糕走红网络 编辑:程序博客网 时间:2024/05/16 03:28

转载:http://blog.sina.com.cn/s/blog_5d3b01030100jvei.html

引用:http://mfg.kingdee.com/pages/chunguangz/blog/archive/2010/03/18/401671.aspx

BW提供了在R3端,自定义数据源的功能,与FILE和WEBSERVICE相比,可以方便ABAP人员开发维护,并且,轻松实现了DELTA 的功能。

自定义的数据源的数据提取方式分为3种:
1)数据库/视图:SAP提供的这种提取方式,系统为你定义好了提取程序,通过在数据库中,设置增量相关字段(如:时间戳、日期、数字),来轻松实现DELTA(增量)抽取,是BW中最常用的自定义数据源,一般是通过程序将数据写入表中。
2) 信息集:即:SAP QUERY。可以设置表间相关的逻辑,相当于JOIN语句,把关联的字段作为数据源。
3) FUNCTION MODULE:通过程序控制数据的提取,可以设置增量字段,也可以不设置,通过一定逻辑将数据抽取,可以实现前两种方式的自定义开发。这是最灵活的自定义数据源。

下面,我们以数据库和FM的方式为例,介绍自定义数据源的应用:
数据库/视图
1. 创建用于数据源的数据表:(SE11将允许表 维护勾选,方便测试)
其中,UPT_TIMESTAMP是我们设置的增量相关字段:

2. 创建自定义数据源:(RSO2)
创 建ZRSO01数据源,点击“创建”:

按以下参数输入,提取结构不允许输入,激活后,系统会为数据源自动创建,点击“一般增量”按钮:

按 以下屏幕输入参数,并保存:
增量字段名:这个字段在数据库中存放了录入时间戳(或日期或数字),数据抽取程序会按照BW请求的时间参数从数据库中 抽取数据。
时间标记:通过时间戳方式实现增量,即:YYYYMMDDhhmmss格式。
日历天数:按照天为单位实现增量。
数字指 针:按照数字增量抽取。
安全间隔上限:如果“时间标记”或“日历天数”勾选,那么此次可以设置,表示将请求时间戳 减去上限设置的间隔后的时间戳作为数据抽取条件。
举例如下:
BW最后一个抽取时间戳为 20100101120000,下次抽取时间为20100101123000,用户在12:25分做了一个记录,直到12:35才保存。这样,这个记录将不被抽取到BW中。我们设置的间隔上限,就是为了防止这样的情况,如我们设置3600,表示在123000抽取的时候,将1小时之前的记录再次抽取一遍,这样防止数据的遗漏。重复抽取的数据只能将对DELTA抽取有影响,我们只能使用通过DSO上载的方式才能保证上载的数据正确。具体的解释将在DELTA 抽取原理文章中介绍。同理,对于数据指针,我们不是设置上限,而是设置下限,请根据您的需求具体设置。
实时的激活:SAP解释是是否适用于RDA 方式的数据源。
更改记录的新状态/附加增量:更改记录的新状态即表示使用后镜像(AIE)的方式上载数据。附加增量表示以ADD方式上载数据。也是DELTA原理的内容,以后在介绍,我们这里选择AIE的方式上载。(简单说就是以最后更改的记录为准上载。ADD即将改变的差额上载)

3. 执行数据源:
接下来,我们要在BW数据源中复制目录下的元数据,并激活数据源,然后创建信息包,此处不再赘述。其中,初始化信息包公司代码被限制为 1003。
向数据库中手工添加数据(SE16):

执行初始化信息包:
我们会在RSA7中,查看多了ZDSO01的初始 化记录和统计信息

点击 ,查看统计记录:
从中,我们可以看出BW系统请求的时间戳为20100318002659。

查 看数据源的请求记录,生成以下记录:
表示数据源中,1003的4条记录被抽取到BW中:

接下来,我们在数据库中在录入2条记 录,如下:

然后执行增量抽取信息包,结果如下,只将一条记录上载
我用的版本比较低,在这里,安全间隔没有起作用。
在上 载前可以使用RSA3测试,可以在FM RSA3_GEN_GET_DATA上设置断点,查看SELECT语句:
* Open Cursor for dynamical SELECT
open cursor with hold g_cursor for
select * from (g_s_oltpsource-extractor)
where (l_t_dynamic_select).
endif.
* Fetch first data package
fetch next cursor g_cursor
appending corresponding fields of table e_t_data
package size g_s_interface-maxsize.

使用Function Module抽取数据
基本与以上步骤相同,我们以提取上例中的表数据为例,在数据源设置FM:

下面介绍FM的创建:
到 SE80中复制FUNCTION GROUP RSAX,到新的FG:

选择RSAX_BIW_GET_DATA_SIMPLE,选择 复制,
复制到我们自己的FM Z_GET_DATA_FM

对FM进行修改,要点如下:
1)将TABLES中的 E_T_DATA的参考值,改为我们的数据源表。

2)修改源程序:程序中,注明文字的地方是需要我们修改的位置。大家可以通过RSA3测试跟踪下效果,此处不再赘述,其他与数据库数据源是一样的。
FUNCTION Z_GET_DATA_FM.
*"----------------------------------------------------------------------
*"*"Local interface:
*" IMPORTING
*" VALUE(I_REQUNR) TYPE SRSC_S_IF_SIMPLE-REQUNR
*" VALUE(I_DSOURCE) TYPE SRSC_S_IF_SIMPLE-DSOURCE OPTIONAL
*" VALUE(I_MAXSIZE) TYPE SRSC_S_IF_SIMPLE-MAXSIZE OPTIONAL
*" VALUE(I_INITFLAG) TYPE SRSC_S_IF_SIMPLE-INITFLAG OPTIONAL
*" VALUE(I_READ_ONLY) TYPE SRSC_S_IF_SIMPLE-READONLY OPTIONAL
*" VALUE(I_REMOTE_CALL) TYPE SBIWA_FLAG DEFAULT SBIWA_C_FLAG_OFF
*" TABLES
*" I_T_SELECT TYPE SRSC_S_IF_SIMPLE-T_SELECT OPTIONAL
*" I_T_FIELDS TYPE SRSC_S_IF_SIMPLE-T_FIELDS OPTIONAL
*" E_T_DATA STRUCTURE ZZC_TEST02 OPTIONAL
*" EXCEPTIONS
*" NO_MORE_DATA
*" ERROR_PASSED_TO_MESS_HANDLER
*"----------------------------------------------------------------------

* Example: DataSource for table SFLIGHT
* tables: sflight. "数据源要输入的数据库表结构,需新建
TABLES: ZZC_TEST02.

* Auxiliary Selection criteria structure
DATA: L_S_SELECT TYPE SRSC_S_SELECT.

* Maximum number of lines for DB table
STATICS: S_S_IF TYPE SRSC_S_IF_SIMPLE,

* counter
S_COUNTER_DATAPAKID LIKE SY-TABIX,

* cursor
S_CURSOR TYPE CURSOR.
* Select ranges
* RANGES: L_R_CARRID FOR SFLIGHT-CARRID, "需修改的选择条件,执行功能组所需的条件,比如日期,公司等
* L_R_CONNID FOR SFLIGHT-CONNID."MY COMMENT
RANGES: L_R_BUKRS FOR T001-BUKRS.
RANGES: L_R_TIMES FOR ZZC_TEST02-UPT_TIMESTAMP.
* Initialization mode (first call by SAPI) or data transfer mode
* (following calls) ?
IF I_INITFLAG = SBIWA_C_FLAG_ON.

************************************************************************
* Initialization: check input parameters
* buffer input parameters
* prepare data selection
************************************************************************

* Check DataSource validity
CASE I_DSOURCE.
* when '0SAPI_SFLIGHT_SIMPLE'. "需改成自己的数据源的名称
WHEN 'ZRSO02'.

WHEN OTHERS.
IF 1 = 2. MESSAGE E009(R3). ENDIF.
* this is a typical log call. Please write every error message like this
LOG_WRITE 'E' "message type
'R3'"message class
'009'"message number
I_DSOURCE"message variable 1
' '."message variable 2
RAISE ERROR_PASSED_TO_MESS_HANDLER.
ENDCASE.

APPEND LINES OF I_T_SELECT TO S_S_IF-T_SELECT.

* Fill parameter buffer for data extraction calls
S_S_IF-REQUNR = I_REQUNR.
S_S_IF-DSOURCE = I_DSOURCE.
S_S_IF-MAXSIZE = I_MAXSIZE.

* Fill field list table for an optimized select statement
* (in case that there is no 1:1 relation between InfoSource fields
* and database table fields this may be far from beeing trivial)
APPEND LINES OF I_T_FIELDS TO S_S_IF-T_FIELDS.

ELSE. "Initialization mode or data extraction ?

************************************************************************
* Data transfer: First Call OPEN CURSOR + FETCH
* Following Calls FETCH only
************************************************************************

* First data package -> OPEN CURSOR
IF S_COUNTER_DATAPAKID = 0.

* Fill range tables BW will only pass down simple selection criteria
* of the type SIGN = 'I' and OPTION = 'EQ' or OPTION = 'BT'.
* 主要的查询逻辑的查询条件
* loop at s_s_if-t_select into l_s_select where fieldnm = 'CARRID'.
* move-corresponding l_s_select to l_r_carrid.
* append l_r_carrid.
* endloop.
*
* loop at s_s_if-t_select into l_s_select where fieldnm = 'CONNID'.
* move-corresponding l_s_select to l_r_connid.
* append l_r_connid.
* endloop.
*
LOOP AT S_S_IF-T_SELECT INTO L_S_SELECT WHERE FIELDNM = 'BUKRS'.
MOVE-CORRESPONDING L_S_SELECT TO L_R_BUKRS.
APPEND L_R_BUKRS.
ENDLOOP.
LOOP AT S_S_IF-T_SELECT INTO L_S_SELECT WHERE FIELDNM =
'UPT_TIMESTAMP'.
MOVE-CORRESPONDING L_S_SELECT TO L_R_TIMES.
APPEND L_R_TIMES.
ENDLOOP.

* Determine number of database records to be read per FETCH statement
* from input parameter I_MAXSIZE. If there is a one to one relation
* between DataSource table lines and database entries, this is trivial.
* In other cases, it may be impossible and some estimated value has to
* be determined.
OPEN CURSOR WITH HOLD S_CURSOR FOR
* SELECT (S_S_IF-T_FIELDS) FROM SFLIGHT "取数逻辑
* WHERE CARRIDIN L_R_CARRID AND
* CONNIDIN L_R_CONNID.

SELECT * FROM ZZC_TEST02
WHERE BUKRSIN L_R_BUKRS
ANDUPT_TIMESTAMP IN L_R_TIMES.

ENDIF. "First data package ?

* Fetch records into interface table.
* named E_T_'Name of extract structure'.
FETCH NEXT CURSOR S_CURSOR
APPENDING CORRESPONDING FIELDS
OF TABLE E_T_DATA
PACKAGE SIZE S_S_IF-MAXSIZE.

IF SY-SUBRC <> 0.
CLOSE CURSOR S_CURSOR.
RAISE NO_MORE_DATA.
ENDIF.

S_COUNTER_DATAPAKID = S_COUNTER_DATAPAKID + 1.

ENDIF. "Initialization mode or data extraction ?

ENDFUNCTION.