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

来源:互联网 发布:安可公关 知乎 编辑:程序博客网 时间:2024/05/22 12:04

转载: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)修改源程序:程序中,注明MY COMMENT的地方是需要我们修改的位置。大家可以通过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.          "MY COMMNET
  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,   "MY COMMENT
         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'.       "MY COMMENT
      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'.
  MY COMMENT
     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            "MY COMMENT
                              WHERE CARRID  IN L_R_CARRID AND
                                    CONNID  IN L_R_CONNID.

      SELECT * FROM ZZC_TEST02
                        WHERE BUKRS         IN L_R_BUKRS
                        AND   UPT_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.

 

原创粉丝点击