流复制不能保证本地和远端的数据库数据完全一致,数据不一致的可能是完全存在的。而且进行插入,更新等操作时,可能因为主键冲突而导致操作失败。以下语句可以查看错误信息:
select * from dba_apply_error;
根据具体事务查找ERROR_MESSAGE:
select * fromdba_apply_error_messages where local_transaction_id='81.23.112827';
如果手工的去查找并排除错误将会非常的耗时,此时就可以利用存储过程来自动化处理这些错误。
这个例子是针对某个事务(p_local_transaction_id )的错误而写的:
核心算法:
IF 操作类型是 insert THEN
获取新行的主键列;
ELSE
获取旧行的主键列;
END IF;
IF 源数据库不存在该条记录 THEN
在远端数据库中删掉该记录;
ELSE
在远端数据库中删掉该记录;
在远端数据库中插入源端对应的记录;
END IF;
具体代码如下:
CREATE OR REPLACE PROCEDURE MANUAL_ERROR(p_local_transaction_idIN VARCHAR2, --处理事务ID
p_output_sql IN VARCHAR2, --是否输出检查和改错SQL
p_deal_error IN VARCHAR2, --是否执行改错SQL
p_delete_errormsg IN VARCHAR2) --是否删除错误信息
is
--edit by leiyaov1.5 2013-12-5
--**********************说明********************************
--1.p_output_sql=1,则输出不同步记录的检查和改错SQL语句。
--2.p_deal_error=1,则执行改错SQL语句。
--3.p_delete_errormsg=1,则删除dba_apply_error里的错误信息。
--**********************************************************
v_count_out int;
ad ANYDATA;
data ANYDATA;
message ANYDATA;
newlist SYS.LCR$_ROW_LIST;
oldlist SYS.LCR$_ROW_LIST;
ret PLS_INTEGER;
lcr SYS.LCR$_ROW_RECORD;
errlog_rec errorlog%ROWTYPE;
--MIS中列最大长度20,表名最大长度24
v_colname VARCHAR2(32);
--err_messages1 VARCHAR2(400);
ob_owner VARCHAR2(32);
ob_name VARCHAR2(32);
cmd_type VARCHAR2(30);
--主键列名及类型
cursor PK_COLS is
SelectB.COLUMN_NAME
from SYS.dba_cons_columns a, SYS.Dba_Tab_Columns b
where a.table_name = B.TABLE_NAME
AND A.table_name = ob_name
and a.column_name = b.COLUMN_NAME
and a.owner = ob_owner
and b.OWNER = A.owner