zoukankan      html  css  js  c++  java
  • 如何回滚请求<复制系统初始的数据>所处理的数据

    一、    问题提出
    请求名称:复制系统初始的数据
    参数:
    问题:
    今天早上财务实施人员新配置了一个OU,然后在跑复制系统初始的数据报表的时候,不小心,不输入参数就直接跑。
    报表先是报错。


    接下来的问题更加严重了。因为这个请求会做很多塞数据的动作,导致一些设定表格数据重复了。
    就是说,原来的业务实体已经存在设定的数据,因为跑这个报表的时候,没有限制业务实体就运行,所以,所有的业务实体的数据都会重新塞一次到相关的表格。
    特别是表格:AR_SYSTEM_PARAMETERS_ALL,当OU数据重复的时候,标准的销售订单,应收应付参数设置等的地方,打开都会报一个异常的错误。


    二、    解决问题的处理过程
    核心问题点:如何回滚?

    这里提出一个有效的解决办法。
    1.      首先,必须要了解[复制系统初始的数据]这个请求究竟是做一个什么样的动作,就是要了解它的代码。

    里面主要是调用ad_morg.replicate_seed_data过程来处理数据。
    而过程ad_morg.replicate_seed_data主要是将一堆表格的数据,从默认的OU(-3113或者-3114)复制数据到目标的业务实体(如果没有输入目标的业务实体,则所有的业务实体都会塞)。

    所以,只要确定2个问题点:
    它会将什么表格里面的什么数据,塞到新的业务实体里面。就可以做一个完整的回滚动作。

    2.      确定该报表自动运行的SQL语句。
    我这里用一个办法,将上面的过程所自动执行的Insert的SQL语句塞到一个表格里面。然后就可以慢慢分析了。
    注意:下面的步骤必须到最新的测试环境做。
    1)        新建临时表格。
    create table XYG.xyg_ad_morg_temp(seq number,statement CLOB,parmeter varchar2(4000));
    CREATE SYNONYM APPS.xyg_ad_morg_temp FOR XYG.xyg_ad_morg_temp;
    2)        新建一个包xyg_ad_morg。
    包xyg_ad_morg和ad_morg一模一样的。注意必须要取消自动执行的动态SQL语句还有COMMIT的语句。
    下面是代码:

    主要是增加:

    还有修改:

    等等。

    3)        接着,执行下面的代码,自动产生数据到临时表。
    declare
      X_org_id number;
    begin
      xyg_ad_morg.g_table_seq := 0;
      dbms_output.enable(1000000);
      X_org_id := null;--to_number('&1');
      xyg_ad_morg.replicate_seed_data(X_org_id,NULL,NULL);

    exception
      when others then
        raise;
    end;

    跑完之后,查询:
    SELECT * FROM xyg_ad_morg_temp ORDER BY SEQ;



    3.      接下来的是重点了,自己编写一道程序,自动验证究竟有多少数据会重复塞到现有的OU里面:
    DECLARE
        L_DEBUG_MODE BOOLEAN := TRUE;
        L_SELECT_STATEMENT varchar2(32767);
        L_DEAL_TABLE   VARCHAR2(240);
        ---
        l_sum_row      number;
        l_sql          VARCHAR(32767);
        l_cursor       NUMBER;
        l_stat         NUMBER;
        ---
        CURSOR CUR_AD_MORG IS
        SELECT * FROM xyg_ad_morg_temp ORDER BY SEQ;
    BEGIN
       dbms_output.enable(1000000);
        FOR REC_AD_MORG IN CUR_AD_MORG LOOP
            l_sum_row := 0;
            ---抓出要处理的表格
            L_DEAL_TABLE := SUBSTR(REC_AD_MORG.STATEMENT
                                  ,INSTR(UPPER(REC_AD_MORG.STATEMENT),' ',1,2)+1
                                  ,INSTR(UPPER(REC_AD_MORG.STATEMENT),' ',1,3)-INSTR(UPPER(REC_AD_MORG.STATEMENT),' ',1,2)-1);
            ----组合SQL语句:
            L_SELECT_STATEMENT := 'SELECT COUNT(*) '||SUBSTR(REC_AD_MORG.STATEMENT,INSTR(UPPER(REC_AD_MORG.STATEMENT),' FROM ',1));
            /*
            IF L_DEBUG_MODE THEN
               DBMS_OUTPUT.PUT_LINE(SUBSTRB(L_SELECT_STATEMENT,1,240));
            END IF;
            */
            l_sql := L_SELECT_STATEMENT;
            
           --dbms_output.put_line(l_sql);
           --打开游标;
           l_cursor := dbms_sql.open_cursor;
           --解析动态SQL语句; dbms_sql.native
           dbms_sql.parse(l_cursor, l_sql, 1);
          
           --绑定变量
           IF REC_AD_MORG.PARMETER LIKE '%-3113%' THEN
              dbms_sql.bind_variable(l_cursor, ':X_source_org_id', -3113);
           ELSE
              dbms_sql.bind_variable(l_cursor, ':X_target_org_id', '');
              dbms_sql.bind_variable(l_cursor, ':X_source_org_id', -3114);
           END IF;
          
            --定义列
           dbms_sql.define_column(l_cursor, 1, l_sum_row);
           --执行动态SQL语句。
           l_stat := dbms_sql.execute(l_cursor);                  

           LOOP
             --fetch_rows在结果集中移动游标,如果未抵达末尾,返回1
              EXIT WHEN dbms_sql.fetch_rows(l_cursor) <= 0;
              --将当前行的查询结果写入上面定义的列中。
              dbms_sql.column_value(l_cursor, 1, l_sum_row);
           END LOOP;
          
           --关闭游标。
           dbms_sql.close_cursor(l_cursor);
          
           ---输出我们想要的结果:
           IF l_sum_row > 0 THEN
            dbms_output.put_line('SEQ:'||REC_AD_MORG.SEQ||' 表格:'||L_DEAL_TABLE||' 自动塞记录行数:'||l_sum_row);
           END IF;
        END LOOP;
    END;

    4.      下面的是日志记录:

    SEQ:1 表格:AP_1096_DATA_ALL 自动塞记录行数:40

    SEQ:5 表格:AP_TOLERANCES_ALL 自动塞记录行数:40

    SEQ:17 表格:AR_SYSTEM_PARAMETERS_ALL 自动塞记录行数:40

    SEQ:49 表格:CN_OBJECTS_ALL 自动塞记录行数:3

    SEQ:51 表格:CN_PERIOD_TYPES_ALL 自动塞记录行数:120

    SEQ:73 表格:CN_TABLE_MAP_OBJECTS_ALL 自动塞记录行数:560

    SEQ:107 表格:OE_PAYMENT_TYPES_ALL 自动塞记录行数:240

    SEQ:109 表格:OE_PAYMENT_TYPES_TL 自动塞记录行数:480

    SEQ:137 表格:OZF_CLAIM_DEF_RULES_ALL 自动塞记录行数:560

    SEQ:141 表格:PO_CHANGE_ORDER_TOLERANCES_ALL 自动塞记录行数:2680

    SEQ:143 表格:CN_CW_WORKBENCH_ITEMS_ALL_B 自动塞记录行数:320

    SEQ:145 表格:CN_CW_WORKBENCH_ITEMS_ALL_TL 自动塞记录行数:640

    SEQ:147 表格:CN_CW_SETUP_TASKS_ALL_B 自动塞记录行数:600

    SEQ:149 表格:CN_CW_SETUP_TASKS_ALL_TL 自动塞记录行数:1200

           还好表格也不多。处理起来应该还是挺方便的。

    5.      最后根据上面的日志的信息,逐个表格处理。
    建议处理步骤:
    1 首先要根据SQL语句,参数,确认一下是否真的有重复塞对应的表。
        如果查询出来的没有数据,则标识一下这个表是没有塞新的数据。
    2 如果查询出来的有数据,则要先备份一下基础数据表(表名+BAK),备份表要建立在XYG下面。
        然后再根据多出来的数据,来清掉。
        例如:
        AP_1096_DATA_ALL
        对应的备份表应该是:XYG.XYG_AP_1096_DATA_ALL_BAK
        如果名字过长,则适当用简称。但是XYG.XYG---BAK是必须要的关键字。
    4 必须要查看对应表格是否有触发器。
    3 备份后,然后再清理掉重复的数据。必须要注意,是重复的才处理!还有,业务实体 ID-3113-3114的不可以动。

    (END)

    今天和Oracle的工程师沟通上了。他们给的处理办法和我处理的结果几乎一样(都是针对这些表格来做数据的重复删除)。
    而且这个文档,貌似在Oracle Meterlink上面是查询不到的(被保密,所以文档ID我就不说明了)。所以顺便贴一下,仅供交流用!
    -----------
    Applies to:
    Oracle Payables - Version: 12.0.6 to 12.0.6
    Oracle Receivables - Version: 12.0.6 to 12.0.6
    Oracle Incentive Compensation - Version: 10.7
    Goal
    During system upgrade, running Replicate Seed Data Concurrent Program to populate the
    Installed modules with Seeded values cause the following data issue:

    Missing records in table AR_MEMO_LINES_ALL_TL and duplicated records in the following
    tables:

    AR_SYSTEM_PARAMETERS_ALL

    AP_1096_DATA_ALL
    AP_TOLERANCES_ALL

    CN_CW_SETUP_TASKS_ALL_TL
    CN_CW_SETUP_TASKS_ALL_B

    The folloiwng errors show up when trying to enter the system options in AR(Account
    Receivable):
    ORA-01422: exact fetch returns more than requested number of rows

    --------------------------------------------------------------
    FRM-40735: POST-QUERY trigger raised unhandled exception ORA-01422.

    Pressing OK. Trying to choose OU with following errors:

    APP-AR-294467: System options already define for this OU.You can only
    view or update this option.

    When trying to Query system options with following errors:
    ORA-01422: exact fetch returns more than requested number of rows
    Solution
    Account Receivable data fix
    ===================

    1. AR_SYSTEM_PARAMETERS_ALL: Log an itar and provide the output of the following query.

    SELECT ROWID, org_id, b.* FROM AR_SYSTEM_PARAMETERS_ALL b
    WHERE org_id in (select org_id from AR_SYSTEM_PARAMETERS_ALL
    group by org_id having count(*) > 1)
    and 1 <= (SELECT Count(*)
    FROM AR_SYSTEM_PARAMETERS_ALL a
    WHERE a.org_id = b.org_id
    AND a.ROWID < b.ROWID)
    order by b.org_id;

    2. AR_MEMO_LINES_ALL_TL: Run the following script to insert the missing records.
    INSERT INTO AR_MEMO_LINES_ALL_TL
    (MEMO_LINE_ID,
    NAME,
    DESCRIPTION,
    LANGUAGE,
    SOURCE_LANG,
    LAST_UPDATE_DATE,
    CREATION_DATE,
    CREATED_BY,
    LAST_UPDATED_BY,
    LAST_UPDATE_LOGIN,
    ORG_ID)
    SELECT /*+ ordered no_expand parallel(a) */
    MEMO_LINE_ID,
    NAME,
    DESCRIPTION,
    LANGUAGE,
    SOURCE_LANG,
    LAST_UPDATE_DATE,
    CREATION_DATE,
    CREATED_BY,
    LAST_UPDATED_BY,
    LAST_UPDATE_LOGIN,
    V.ORGANIZATION_ID
    FROM AR_MEMO_LINES_ALL_TL A,
    (SELECT /*+ no_merge */
    ORGANIZATION_ID
    FROM FND_PRODUCT_GROUPS, HR_OPERATING_UNITS
    WHERE PRODUCT_GROUP_ID = 1
    AND MULTI_ORG_FLAG = 'Y'
    UNION
    SELECT NULL
    FROM DUAL
    WHERE NOT EXISTS (SELECT NULL
    FROM FND_PRODUCT_GROUPS
    WHERE MULTI_ORG_FLAG = 'Y')) V
    WHERE NVL(a.ORG_ID, -99) = NVL(-3113, -99)
    AND NOT (a.ORG_ID = -3114 AND V.ORGANIZATION_ID IS NOT NULL)
    AND (A.MEMO_LINE_ID,A.LANGUAGE, NVL(V.ORGANIZATION_ID, -99)) NOT IN
    (SELECT /*+ hash_aj parallel(b) */
    MEMO_LINE_ID, LANGUAGE, NVL(ORG_ID, -99)
    FROM AR_MEMO_LINES_ALL_TL B
    WHERE B.MEMO_LINE_ID = A.MEMO_LINE_ID
    AND B.LANGUAGE = A.LANGUAGE
    AND nvl(B.org_id,-99)=nvl(V.ORGANIZATION_ID,-99));


    Incentive Compensation data fix
    =====================

    delete from CN_CW_SETUP_TASKS_ALL_B c1
    where c1.rowid = (select max(rowid)
    from CN_CW_SETUP_TASKS_ALL_B c2
    where c1.org_id = c2.org_id
    and c1.setup_task_code = c2.setup_task_code
    and c1.workbench_item_code = c2.workbench_item_code
    and c1.setup_task_sequence = c2.setup_task_sequence
    and c1.setup_task_status = c2.setup_task_status
    group by org_id, setup_task_code, workbench_item_code,
    setup_task_sequence, setup_task_status
    having count(1) > 1 ) ;

    -- should have 15 records per org_id for cn_cw_setup_tasks_all_b

    delete from CN_CW_SETUP_TASKS_ALL_TL c1
    where c1.rowid = (select max(rowid)
    from CN_CW_SETUP_TASKS_ALL_TL c2
    where c1.org_id = c2.org_id
    and c1.setup_task_code = c2.setup_task_code
    and c1.language = c2.language
    and c1.source_lang = c2.source_lang
    and c1.setup_task_name = c2.setup_task_name
    and c1.setup_task_description = c2.setup_task_description
    group by org_id, setup_task_code, language,
    source_lang, setup_task_name, setup_task_description
    having count(1) > 1 ) ;

    -- should have 15 records per org_id per language for cn_cw_setup_tasks_all_tl


    Account Payables data fix
    =================

    Table AP_TOLERANCES_ALL has been obsoleted, and is not used anywhere any longer.

    Table AP_1096_DATA_ALL is simply a container for the summary information for the 1099 suppliers, and the data gets deleted and re-created, on running the 1099 reports.

    Please log a new itar if the duplicated data cause any other issue in AP.


    The code fix is addressed by the following bugs:

    Bug:8302210 (AD) - REPLICATE SEED DATA PROGRAM INSERT DUPLICATE ROWS IN AR_SYSTEM_APRAMETERS_ALL

    Bug:7828394 (AR) - REPLICATE SEED DATA PROGRAM INSERT DUPLICATE ROWS IN AR_SYSTEM_APRAMETERS_ALL


    来自:http://www.itpub.net/thread-1803604-1-12.html

  • 相关阅读:
    loj 1257 (求树上每一个点到树上另一个点的最长距离)
    loj 1032 数位dp
    loj 1030概率dp
    loj1011 状态压缩
    java大数取模
    求阶乘的位数
    loj 1426(dfs + bfs)
    携程greenlet模块使用
    如何让socket编程非阻塞?
    分别用request和socket给百多发送请求
  • 原文地址:https://www.cnblogs.com/wanghang/p/6299269.html
Copyright © 2011-2022 走看看