需求:查找物化视图日志中的数据。
背景:两个数据库,为了同步。在其中一个数据库的表上建物化视图日志,当表的数据有更新,对应的物化视图日志就会有相应记录。详细的创建、查询物化视图日志的介绍见下文附录。
ps: 下文开始,物化视图日志用mvlog 代替。
首先声明不知道还没有别的办法,自己想到就是这个土办法。
1 查找到所有mvlog ;
2 找到所有涉及到的表的主键列;
3 查询每个mvlog中的主键的值。
1 查询所有的mvlog,找到表名和mvlog表名
1 SELECT MASTER, LOG_TABLE FROM DBA_MVIEW_LOGS WHERE LOG_OWNER = UPPER(?)
注:这里的参数和2的
OWNER的参数值是一样的,都是数据库用户名(登录用的)。
2 用1查询到的每个表名去查询那个表的主键列。
1 " SELECT T2.COLUMN_NAME "
2 + " FROM DBA_CONSTRAINTS T1, DBA_IND_COLUMNS T2 "
3 + " WHERE T1.TABLE_NAME =UPPER(?) "
4 + " AND T2.TABLE_NAME=T1.TABLE_NAME "
5 + " AND T1.CONSTRAINT_TYPE='P' "
6 + " AND T1.INDEX_NAME = T2.INDEX_NAME "
7 + " AND T1.OWNER=UPPER(?) ";
注:参数1就是1查询到的“MASTER”的值。
3 用1查询到的每个mvlog表去查询2查询到的每个主键列的值
1 " SELECT DISTINCT "
2 while () {
3 @2@COLUMN_NAME + ","
4 }
5 " FROM @1@LOG_TABLE "
这样就得到了,每个mvlog中的主键的值。
附录:1创建mvlog
1 create materialized view log on marea with primary key,rowid,
sequence (AREA_NM_R, AREA_NM_N) including new values;
primary key是主键,rowid是表更新涉及的行号,sequence是序列对,自由添加。
2查询mvlog
查询mvlog和查询表是一样的,简单的查询语句就可以。
1 select * from mlog$_marea
关于mvlog 的介绍目前只接触到这些,To be continued...
文中涉及到的DBA_MVIEW_LOGS,DBA_CONSTRAINTS,DBA_IND_COLUMNS 也有必要介绍下,不过看字面意思还是能望而生义的...
------------------------------我是分割线----------------------------------
因为对DBA表不甚了解,项目开发的时候果然出了点问题。
客户后来要求不要用DBA的表,改用USER表。因为考虑到商用环境,用户一般不会给予DBA权限。
所以两段SQL文稍有修改:
1 查询所有的mvlog,找到表名和mvlog表名
1
SELECT MASTER, LOG_TABLE FROM USER_MVIEW_LOGS
2 用1查询到的每个表名去查询那个表的主键列。
1
"
SELECT T2.COLUMN_NAME
"
2
+
"
FROM USER_CONSTRAINTS T1, USER_IND_COLUMNS T2
"
3
+
"
WHERE T1.TABLE_NAME =UPPER(?)
"
4
+
"
AND T2.TABLE_NAME=T1.TABLE_NAME
"
5
+
"
AND T1.CONSTRAINT_TYPE='P'
"
6
+
"
AND T1.INDEX_NAME = T2.INDEX_NAME
"
;
注:主要就是将DBA表->USER表,并把OWNER和LOG_OWNER的限制去掉了,因为USER表对应的肯定是用户本身,也就没有必要限制了。