BW:SID冲突:问题描述及处理 By Greed_zy

问题描述1

0COORDER上载数据的时候,提示SID冲突。(错误详见问题模拟)

问题描述2

在激活DSO的时候提示错误

   

BW:SID冲突:问题描述及处理 By Greed_zy_第1张图片

   

错误日志如下:

   

Could not enter feature 410000278286 with SID 3775474 into table /BI0/SCOORDE

   

到S表中查找发现,这个SID已经被占用:

   

BW:SID冲突:问题描述及处理 By Greed_zy_第2张图片

问题分析:

手工创建订单的程序中,使用ABAP代码计算出当前SID的最大值,然后加1,填充到0COORDER的S表中。而SAP在进行数据加载时,会调用系统自身的Number Range Object(即号码池),从中获得编号并赋值给SID。

这样问题就出来了,我们手工创建的单号会占用一个SID,而系统并不知道这些,依然会根据号码池的状态来确定SID。也就是说系统加载的时候所使用的SID是被手工订单占用的。

问题模拟:

下面我们就简单的模拟一下这个流程:

   

  • TCODE:SNRO

       

    BW:SID冲突:问题描述及处理 By Greed_zy_第3张图片

       

    BIM0000394(这个可以到Table:TNROT中通过查找描述得到)

       

    BW:SID冲突:问题描述及处理 By Greed_zy_第4张图片

       

    我们首先去看当前的编码:

       

    BW:SID冲突:问题描述及处理 By Greed_zy_第5张图片

       

    SAP上载数据的时候,会更新编码流的状态。当前状态为750128。

       

  • TCODE:Z100

       

    在创建订单的时候,使用手工的方式写入0COORDER,同时取SID的最大值,并加1。

       

    BW:SID冲突:问题描述及处理 By Greed_zy_第6张图片

       

    相关代码如下:

       

      SELECT SINGLE MAX( sid ) FROM /bi0/scoorder INTO l_scoorder-sid

      WHERE coorder <> ''.

       

      l_scoorder-sid = l_scoorder-sid + 1.

      l_scoorder-coorder = p_order.

      INSERT /bi0/scoorder FROM l_scoorder.

       

    我们填充完Z00112010022之后,看到号码池中,当前的编码依然是750128,而在S表里,SID值750129已经被占用。

       

  • TCODE:RSA1

       

    我们模拟SAP的ETL,主要是测试DTP把数据从PSA抽到0COORDER时,S表里如何处理SID被占用的问题。

       

    BW:SID冲突:问题描述及处理 By Greed_zy_第7张图片

       

    Table:/BI0/SCOORDER

    首先我们在数据源Z_COORDER的PSA中新制作了三条数据。

       

    BW:SID冲突:问题描述及处理 By Greed_zy_第8张图片

       

    之后上载DTP,提示错误:

       

    BW:SID冲突:问题描述及处理 By Greed_zy_第9张图片

       

    然后,我们到S表中查看记录发现:

       

    BW:SID冲突:问题描述及处理 By Greed_zy_第10张图片

       

    在111111111117的时候,发现SID被占用而跳过了这条数据,并报错。111111111118和111111111119添加成功。

    PS:我们关注了当前的0COORDER的P表,发现这里没有我们新加载的这几条数据。而S表中却已经填充了两条记录。

       

    此时,Number Range Object的当前状态为:750131。

       

    BW:SID冲突:问题描述及处理 By Greed_zy_第11张图片

       

    再次加载DTP,上载成功。

    这样问题就解开了:

    再次加载DTP的时候,系统去查找P表,发现数据不存在,就又去申请了3个SID,此时号码池的编号为750134,而这次加载只是在S表里添加了一条记录,111111111117,它的SID为750132,这时就发生了跳号的情况。也就是说,只要SID被占用,系统就会往下继续申请SID,如果申请的数据量足够大,超过手工录入的SID,上载就不会报错。

    这就是为什么之前DTP上载出错,再次上载就会成功的原因。

    PS:此时P表的数据是存在的。

       

    BW:SID冲突:问题描述及处理 By Greed_zy_第12张图片

       

    BW:SID冲突:问题描述及处理 By Greed_zy_第13张图片

       

    BW:SID冲突:问题描述及处理 By Greed_zy_第14张图片

       

    解决方案:

    使用系统标准函数,直接取号码池的数据,这样就可以规避SID冲突的问题。

    相关代码如下:

      CALL FUNCTION 'NUMBER_GET_NEXT'

      EXPORTING

        NR_RANGE_NR = '01'

        OBJECT = 'BIM0000394'

      IMPORTING

        NUMBER = l_scoorder-sid.

       

    PS:如果手工录入和系统上载在同一时间,有可能出现抢到相同编号的情况,还可以使用系统的'NUMBER_RANGE_ENQUEUE' 和'NUMBER_RANGE_DEQUEUE' 来解决。

       

    相关代码如下:

      CALL FUNCTION 'NUMBER_RANGE_ENQUEUE'

        EXPORTING

          OBJECT           = 'BIM0000394'

        EXCEPTIONS

          foreign_lock     = 1

          object_not_found = 2

          system_failure   = 3

          OTHERS           = 4.

      CASE sy-subrc.

        WHEN 1.

          MESSAGE E024(NR).

        WHEN 2.

          MESSAGE 'object_not_found' TYPE 'E'.

        WHEN 3.

          MESSAGE 'system_failure' TYPE 'E'.

        WHEN 4.

          MESSAGE 'OTHERS' TYPE 'E'.

      ENDCASE.

       

      IF sy-subrc EQ 0.

        CALL FUNCTION 'NUMBER_GET_NEXT'

          EXPORTING

            nr_range_nr   = '01'

            OBJECT        = 'BIM0000394'

            ignore_buffer = 'X'

          IMPORTING

            number        = O_INT.

        CALL FUNCTION 'NUMBER_RANGE_DEQUEUE'

          EXPORTING

            OBJECT           = 'BIM0000394'

          EXCEPTIONS

            object_not_found = 1

            OTHERS           = 2.

      ENDIF.

       

    这样,当有程序在使用这个号码池的时候,就会报错:

你可能感兴趣的:(BW:SID冲突:问题描述及处理 By Greed_zy)