引子
这是测试环境存在了很久的问题。由于基础配置信息(如:代理人信息)不像生产环境有专人维护,常常会有数据过期,导致无法使用的情况。
而很多配置数据是在外围系统维护(如代理人信息,在销管系统)以往的解决办法:
1. 联系销售管理系统协助配置。
2. 审核通过后同步到核心,然后出单
问题点:因为需要其他人配合,有等待;碰到大量数据配置时对配置人员来说很麻烦。
1. 解决方案(版本1.1)
工具:数据库存过
思路:需要导入数据的表放在数据库中。遍历这些表,在遍历过程中先删除表中符合条件的数据,然后将生产环境符合条件的数据迁入到当前环境中
/*****************************************************************************\ * Name: P_IMPORT_CHA_DATA * PROCEDURE: 导生产环境基础数据(代理人信息) * Paramater: IC_C_CHA_CDE 代理人代码 * Programmer: lyt * Date: 2019/10/12 * Update: * 需导入表配置:T_IMPORT_TABLE WHERE C_MARK = '2'; * 维护dbquery中间库表结构:SELECT 'CREATE TABLE T_' || C_TABLE || ' AS SELECT * FROM ZSSYS.' || C_TABLE || ' WHERE ROWNUM = 0;',A.* FROM T_IMPORT_TABLE A; * 如果手续费打包时提示:算税平台找不到该代理人,需联系算税平台(沈一栋)邵先路,将算税生产环境信息同步到对应环境 \*****************************************************************************/ PROCEDURE P_IMPORT_CHA_DATA(IC_C_CHA_CDE VARCHAR2) AS LB_SQL CLOB; LB_COLS CLOB; LB_COND CLOB; LN_ROWS NUMBER; CURSOR CUR_TABLE IS SELECT * FROM T_IMPORT_TABLE WHERE C_MARK = '2'; BEGIN FOR LR_TABLE IN CUR_TABLE LOOP SELECT WM_CONCAT(COLUMN_NAME) INTO LB_COLS FROM USER_TAB_COLS@LINK_CORE WHERE TABLE_NAME = 'T_' || UPPER(LR_TABLE.C_TABLE) ORDER BY COLUMN_ID; LB_COND := ' WHERE '; IF (UPPER(LR_TABLE.C_TABLE) = 'WEB_CUS_COM_ACCT') THEN LB_COND := LB_COND || 'C_REL_CDE '; ELSIF (UPPER(LR_TABLE.C_TABLE) = 'WEB_CUS_CONFER') THEN LB_COND := LB_COND || 'C_CLNT_CDE '; ELSIF (UPPER(LR_TABLE.C_TABLE) = 'WEB_CUS_CONFER_DTL' OR UPPER(LR_TABLE.C_TABLE) = 'WEB_AUTH_CONFER') THEN LB_COND := LB_COND || 'C_AGT_AGR_NO IN (SELECT C_AGT_AGR_NO FROM ZSSYS.WEB_CUS_CONFER WHERE C_CLNT_CDE'; ELSIF (UPPER(LR_TABLE.C_TABLE) = 'WEB_ORG_SALES') THEN LB_COND := LB_COND || 'C_SLS_CDE IN(SELECT C_SLS_CDE FROM ZSSYS.WEB_CUS_CHA WHERE C_CHA_CDE'; ELSE LB_COND := LB_COND || 'C_CHA_CDE '; END IF; IF (UPPER(LR_TABLE.C_TABLE) = 'WEB_CUS_CONFER_DTL' OR UPPER(LR_TABLE.C_TABLE) = 'WEB_AUTH_CONFER' OR UPPER(LR_TABLE.C_TABLE) = 'WEB_ORG_SALES') THEN LB_COND := LB_COND || '= ''' || IC_C_CHA_CDE || ''')'; ELSE LB_COND := LB_COND || '= ''' || IC_C_CHA_CDE || ''''; END IF; LB_SQL := 'DELETE FROM ZSSYS.' || LR_TABLE.C_TABLE || LB_COND; EXECUTE IMMEDIATE LB_SQL; LB_SQL := 'INSERT INTO ZSSYS.' || LR_TABLE.C_TABLE || '(' || LB_COLS || ') SELECT ' || LB_COLS || ' FROM ' || 'ZSSYS.' || LR_TABLE.C_TABLE || '@LINK_CORE '|| LB_COND; EXECUTE IMMEDIATE LB_SQL; END IF; END LOOP; --COMMIT; END P_IMPORT_CHA_DATA;
涉及知识点
1.1 oracle 中的for循环
FOR LR_TABLE IN CUR_TABLE LOOP
END LOOP;
1.2 oracle 中的条件分支语句
IF () THEN
...;
ELSIF () THEN
...;
ELSE
...;
END IF;
1.3 存过中入参
1.4 游标 cursor
Cursor类型包含三种: 隐式Cursor,显式Cursor和Ref Cursor(动态Cursor)。
1). 隐式游标:无需定义,Select /Update / Insert/Delete操作,就是隐式Cursor
2). 显式游标:
cursor <cursor>[(<param_list>)]is <select_statement>;
3). 动态游标:
Type [Cursor type name] is ref cursor
游标的属性(4个)1.found 2.notfound 3.rowcount 4.isopen
2. 存过怎么调试?
2.1 如何打断点
2.2 如何调试
首先在左侧列表中,选中对应存过,右键后点击add debug informaintion(添加调试信息),然后在点Test,显示如下页面:
最上面一排是debug相关按键区域,中间为代码显示部分,左下为变量值显示区域(填写变量名称,执行过程中查看变量值)
2. 解决方案(版本1.2)
版本1.1存在的问题:由于部分表之间存在外键约束,导致删除操作失败。
解决思路:先反向遍历表完成全部删除操作(删除符合条件的数据),在遍历表完成插入操作,这里用到动态索引
/*****************************************************************************\ * Name: P_IMPORT_CHA_DATA * PROCEDURE: 导生产环境基础数据(代理人信息) * Paramater: IC_C_CHA_CDE 代理人代码 * Programmer: lyt * Date: 2019/10/12 * Update: * 需导入表配置:T_IMPORT_TABLE WHERE C_MARK = '2'; * 如果手续费打包时提示:算税平台找不到该代理人,需联系算税平台(沈一栋)邵先路,将算税生产环境信息同步到对应环境 \*****************************************************************************/ PROCEDURE P_IMPORT_CHA_DATA(IC_C_CHA_CDE VARCHAR2) AS TYPE ref_cursor_type IS REF CURSOR; CUR_TABLE ref_cursor_type; LR_TABLE ZSSYS.T_IMPORT_TABLE%ROWTYPE; LB_SQL CLOB; LB_COLS CLOB; LB_COND CLOB; BEGIN FOR i IN 1 .. 2 LOOP IF (i = 1) THEN OPEN CUR_TABLE FOR SELECT * FROM ZSSYS.T_IMPORT_TABLE WHERE C_MARK = '2' ORDER BY C_TABLE_NO DESC; ELSE OPEN CUR_TABLE FOR SELECT * FROM ZSSYS.T_IMPORT_TABLE WHERE C_MARK = '2' ORDER BY C_TABLE_NO; END IF; LOOP FETCH CUR_TABLE INTO LR_TABLE; EXIT WHEN CUR_TABLE%NOTFOUND; SELECT WM_CONCAT(COLUMN_NAME) INTO LB_COLS FROM DBA_TAB_COLS@LINK_CORE WHERE TABLE_NAME = 'T_' || UPPER(LR_TABLE.C_TABLE) AND OWNER = 'ZSSYS' ORDER BY COLUMN_ID; LB_COND := ' WHERE '; IF (UPPER(LR_TABLE.C_TABLE) = 'WEB_CUS_COM_ACCT') THEN LB_COND := LB_COND || 'C_REL_CDE '; ELSIF (UPPER(LR_TABLE.C_TABLE) = 'WEB_CUS_CONFER') THEN LB_COND := LB_COND || 'C_CLNT_CDE '; ELSIF (UPPER(LR_TABLE.C_TABLE) = 'WEB_CUS_CONFER_DTL' OR UPPER(LR_TABLE.C_TABLE) = 'WEB_AUTH_CONFER') THEN LB_COND := LB_COND || 'C_AGT_AGR_NO IN (SELECT C_AGT_AGR_NO FROM ZSSYS.WEB_CUS_CONFER@LINK_CORE WHERE C_CLNT_CDE'; ELSIF (UPPER(LR_TABLE.C_TABLE) = 'WEB_ORG_SALES') THEN LB_COND := LB_COND || 'C_SLS_CDE IN(SELECT C_SLS_CDE FROM ZSSYS.WEB_CUS_CHA@LINK_CORE WHERE C_CHA_CDE'; ELSE LB_COND := LB_COND || 'C_CHA_CDE '; END IF; IF (UPPER(LR_TABLE.C_TABLE) = 'WEB_CUS_CONFER_DTL' OR UPPER(LR_TABLE.C_TABLE) = 'WEB_AUTH_CONFER' OR UPPER(LR_TABLE.C_TABLE) = 'WEB_ORG_SALES') THEN LB_COND := LB_COND || '= ''' || IC_C_CHA_CDE || ''')'; ELSE LB_COND := LB_COND || '= ''' || IC_C_CHA_CDE || ''''; END IF; IF (i = 1) THEN LB_SQL := 'DELETE FROM ZSSYS.' || LR_TABLE.C_TABLE || LB_COND; ELSE LB_SQL := 'INSERT INTO ZSSYS.' || LR_TABLE.C_TABLE || '(' || LB_COLS || ') SELECT ' || LB_COLS || ' FROM ' || 'ZSSYS.' || LR_TABLE.C_TABLE || '@LINK_CORE' || LB_COND; END IF; EXECUTE IMMEDIATE LB_SQL; END LOOP; IF CUR_TABLE%ISOPEN THEN --close cursor CLOSE CUR_TABLE; END IF; END LOOP; END P_IMPORT_CHA_DATA;