如何回滚请求<复制系统初始的数据>所处理的数据
来源:互联网 发布:英国的域名后缀 编辑:程序博客网 时间:2024/06/03 20:22
如何回滚请求[复制系统初始的数据]所新增的数据
2013-7-19
Sam.T
一、 问题提出
请求名称:复制系统初始的数据
参数:空
问题:
今天早上财务实施人员新配置了一个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 备份后,然后再清理掉重复的数据。必须要注意,是重复的才处理!还有,OUID是-3113和-3114的不可以动。
(END)
相关的附件在DOC文档里面。
- 如何回滚请求<复制系统初始的数据>所处理的数据
- 如何回滚请求<复制系统初始的数据>所处理的数据
- 如何处理控件所包含的数据的操作细节
- 如何处理post请求方JSON数据传递的问题
- WinSocket如何处理一个典型的数据请求
- mysql_escape_string导致的数据回滚
- MySQL数据无法回滚的原因
- ThinkPHP数据回滚的使用简介
- 首页初始数据的生成
- 该如何设置数据连接池的初始大小
- 该如何设置数据连接池的初始大小
- 所处理的数据在什么地方 有多长 如何定义 如何寻找
- ajax请求中json数据的处理
- json格式数据的请求处理
- Ajax请求数据并处理的笔记
- httpClient请求及返回数据的处理
- tornado处理post请求的json数据
- 网络请求数据 有null 的处理
- MyEclipse8.6+Flash Builder 4.0 plug-in创建Flex-J2EE程序
- Python100例——第五章----不定方程的解
- 禁用掉KDTable向下和回车新增行事件
- Android详细的对话框AlertDialog.Builder使用方法
- Servlet API
- 如何回滚请求<复制系统初始的数据>所处理的数据
- mysql 慢查询日志(slow_query_log_file)切换
- Python100例——第六章----分数趣题
- android ProgressBar
- http://subject.csdn.net/sohu/
- 大型互联网算法面试题
- C语言中的字符串
- Python100例——第七章----逻辑推理与判断
- mongodb编译