oracle如何利用触发器对物化视图刷新进行定制

物化视图的刷新其实和普通的SQL执行没有什么本质的区别,因此也可以通过在物化视图上创建触发器的方式,对刷新操作进行定制。

正好前两天有人在BLOG上问我,如果在物化视图添加一个时间戳列,并在物化视图更新的时候,自动维护这个列。其实很简单,通过触发器就可以达到这个目的:

SQL> CREATE TABLE T (ID NUMBER PRIMARY KEY, NAME VARCHAR2(30));

表已创建。

SQL> INSERT INTO T SELECT ROWNUM, TNAME FROM TAB;

已创建25行。

SQL> COMMIT;

提交完成。

SQL> CREATE MATERIALIZED VIEW LOG ON T;

实体化视图日志已创建。

SQL> CREATE TABLE MV_T (ID NUMBER, NAME VARCHAR2(30), TIME DATE DEFAULT SYSDATE);

表已创建。

SQL> CREATE MATERIALIZED VIEW MV_T ON PREBUILT TABLE REFRESH FAST

2  AS SELECT * FROM T;

实体化视图已创建。

SQL> ALTER SESSION SET NLS_DATE_FORMAT = 'YYYY-MM-DD HH24:MI:SS';

会话已更改。

SQL> SELECT * FROM T WHERE ID = 1;

ID NAME

---------- ------------------------------

1 T_AB

SQL> SELECT * FROM MV_T WHERE ID = 1;

未选定行

SQL> EXEC DBMS_MVIEW.REFRESH('MV_T', 'C')

PL/SQL过程已成功完成。

SQL> SELECT * FROM MV_T WHERE ID = 1;

ID NAME                           TIME

---------- ------------------------------ -------------------

1 T_AB                           2009-06-21 00:05:09

SQL> UPDATE T SET NAME = 'A' WHERE ID = 1;

已更新1行。

SQL> COMMIT;

提交完成。

SQL> EXEC DBMS_MVIEW.REFRESH('MV_T', 'F')

PL/SQL过程已成功完成。

SQL> SELECT * FROM MV_T WHERE ID = 1;

ID NAME                           TIME

---------- ------------------------------ -------------------

1 A                              2009-06-21 00:05:09

本文URL地址:http://www.bianceng.cn/database/Oracle/201410/45472.htm

在这个例子中建立一个ON PREBUILT TABLE类型的物化视图,其中物化视图的基表比主表要多了一个字段,并为这个字段设置了默认值。

物化视图在完全刷新的时候会自动在这个字段中写入默认值,但是如果基表进行了更新操作,则物化视图中新增的时间戳字段并不会在刷新的时候自动更新。

其实解决这个问题的方法很简单,一个UPDATE触发器就可以了:

SQL> CREATE OR REPLACE TRIGGER MV_T

2  BEFORE UPDATE ON MV_T

3  FOR EACH ROW

4  BEGIN

5  :NEW.TIME := SYSDATE;

6  END;

7  /

触发器已创建

SQL> UPDATE T SET NAME = 'B' WHERE ID = 1;

已更新1行。

SQL> COMMIT;

提交完成。

SQL> SELECT * FROM MV_T WHERE ID = 1;

ID NAME                           TIME

---------- ------------------------------ -------------------

1 A                              2009-06-21 00:05:09

SQL> EXEC DBMS_MVIEW.REFRESH('MV_T', 'F')

PL/SQL过程已成功完成。

SQL> SELECT * FROM MV_T WHERE ID = 1;

ID NAME                           TIME

---------- ------------------------------ -------------------

1 B                              2009-06-21 00:14:01

只需要处理UPDATE操作就可以了,因为DELETE不涉及到这个问题,而INSERT操作由于表的时间戳字段设置了默认值,因此不需要触发器进行额外的设置:

SQL> INSERT INTO T VALUES (26, 'C');

已创建1行。

SQL> EXEC DBMS_MVIEW.REFRESH('MV_T', 'F')

PL/SQL过程已成功完成。

SQL> SELECT * FROM MV_T WHERE ID = 26;

ID NAME                           TIME

---------- ------------------------------ -------------------

26 C                              2009-06-21 00:14:42

时间: 2024-09-13 06:01:40

oracle如何利用触发器对物化视图刷新进行定制的相关文章

oracle基于COMMIT SCN的物化视图日志快速刷新的方法

11.2中物化视图日志可以指定COMMIT SCN,这时物化视图刷新就不需要时间戳了,这篇简单描述Oracle是如何实现通过COMMIT SCN来进行刷新的. 建立一个测试环境: SQL> SELECT * FROM V$VERSION; BANNER -------------------------------------------------------------------------------- Oracle Database11gEnterprise Edition Relea

物化视图刷新原理与性能诊断

参考文档:Materialized View Refresh: Locking, Performance, Monitoring (文档 ID 258252.1) How to Monitor the Progress of a Materialized View Refresh (MVIEW) (文档 ID 258021.1) 1.名词解释: 基表 指的是英文里面的Master Table和Master Materialized View,并不只是只一个表,而是创建MView的时候所需要用到的

[20150705]12c物化视图刷新Out of place2

[20150705]12c物化视图刷新Out of place2.txt --11G物化视图刷新有1个参数atomic_refresh. --如果为false,采用的方式是truncate,再使用/*+ append */ 提示insert.这样redo最少,但是刷新期间无法访问. --如果为true,采用的方式是delete,再insert.这样产生许多redo与undo.这样在刷新期间访问没问题,最多有点慢. --自己做一个测试: --12c在这个基础上引入1个参数Out of place,

[20150629]物化视图刷新atomic_refresh.txt

[20150629]物化视图刷新atomic_refresh.txt --11G物化视图刷新有1个参数atomic_refresh. --如果为false,采用的方式是truncate,再使用/*+ append */ 提示insert.这样redo最少,但是刷新期间无法访问. --如果为true,采用的方式是delete,再insert.这样产生许多redo与undo.这样在刷新期间访问没问题,最多有点慢. --自己做一个测试: 1.建立测试环境: SCOTT@test> @ver1 PORT

特殊的物化视图刷新

现在有一个需求,某个环境中存在两个用户,一个用户中存在物化视图,另一个用户中存在源表,根据业务的需要,需要做一种特别的物化视图刷新. 物化视图用户中的物化视图为CORP_NAME 源数据用户中的表为ADD_CORP_NAME 可能数据刷新是没有问题,关键就是在于CORP_NAME中的字段要比ADD_CORP_NAME多一些.CORP_NAME           ADD_CORP_NAME CORP_ID               |  CORP_ID            SYS_CREAT

物化视图刷新结合ADG的尝试

之前写过一篇 物化视图刷新结合ADG的尝试,想必绝大多数的朋友看完再没有深究,其实也有些朋友做了建议,让我尝试prebuilt来做.这种数据迁移方式用的比较少,但是个人感觉还是很不错的.如果迁移的表不是很多,这种迁移方式还是非常强大的. 如果一个表非常大,我目前的设想就是通过ADG备库来把数据首先同步到统计库中,然后在主库端通过物化视图日志来增量刷新. 使用物化视图 prebuilt的方式确实可以实现,我产生了几个疑问,物化视图日志该什么时候创建.创建的时间太早或者太晚,对于增量刷新是否有影响,

物化视图刷新失败导致日志表异常增大

整理自:http://blog.itpub.net/231499/viewspace-63714/ 今天在检查时,发现某个物化视图日志占用的空间超过150M,再检查看,该物化视图日志表的记录数有150W,由于其对应的物化视图没有会刷新一次,结合业务量分析可知:物化视图日志不能正常清除. 下面的解决步骤 --在源库查询物化视图对应日志条目个数SQL> select count(1) from MLOG$_ITEM_TAG; COUNT(1)----------532515 --在物化视图端刷新物化

物化视图刷新的问题及分析

最近现场需要搭建一套全新的环境,对于数据字典的管理采用了物化视图,因为数据量不大,采用了全量刷新的方式.因为有好几套环境,有几套环境是通过db link和主节点的表创建的物化视图,这几个节点间的网络情况不好,刷新一个稍微大一些的表或者带有lob字段的表时,速度会很慢,因为有好几套环境,一套一套的等待刷新完得花费不少的时间,所以自己想写一个shell脚本让它在后台慢慢跑,这样过一段时间再看看日志保证数据都已经刷新完毕就可以了. 原本采用的方式是 create materialized view x

oracle 11g-基于rowid的物化视图没有数据?????

问题描述 基于rowid的物化视图没有数据????? 本人刚刚接触物化视图,有些地方不太清楚,刚创建好的物化视图没有数据是几个意思啊? select 后面是多个表左连接,用的是(+)而不是left join ,哪位大神搭救一下??谢谢 create materialized view V_SHIPOWNER_ALL_TEST refresh complete on demand start with to_date('07-09-2015 12:00:00', 'dd-mm-yyyy hh24: