视图上触发器 & Materialized View 物化视图

视图是基于一个表或多个表或视图的逻辑表, 本身不包含数据,只是存储在数据字典里的一条select语句;所以,通过视图做查询并不能提高查询效率。
怎样对连接多表的视图进行DML操作?
在Oracle系统里,如果一个视图是由一个基表的所有非空列(Not   Null)组成,那么该视图是可以进行INSERT、DELETE和UPDATE操作的。
但是如果一个视图由多个基表进行连接(Join)而成,则该视图不允许进行INSERT、DELETE和UPDATE操作的。
引用
如,对联接视图来自不同基表的多个字段做update,会报:ORA-01776: 无法通过联接视图修改多个基表

而Oracle提供的替代触发器(Instead   of   Trigger)就是用于对连接视图进行Insert、Delete、Update操作的触发器。也就是说,通过编写替代触发器,可以对连接视图进行DML操作,从而实现对各基表数据的修改。
引用

Only INSTEAD OF triggers can be created on a view.
如欲在视图上创建before或after trigger,会报:
引用
ORA-25001: 无法在视图上创建此类型的触发器

INSTEAD OF triggers are valid only for views. You cannot specify an INSTEAD OF trigger on a table.
You can read both the :OLD and the :NEW value, but you cannot write either the :OLD or the :NEW value.


关于INSTEAD OF view : http://download.oracle.com/docs/cd/B12037_01/server.101/b10759/statements_7004.htm
例子: http://www.devx.com/tips/Tip/21433
  create or replace trigger 名称
  Instead Of Insert or update or delete
  on 视图
  for each row
  Declare
  begin
  If Inserting Then
  Insert Into 基本表1 (t11,t12) Values (:New.f1,:New.f2);
  Insert Into 基本表2 (t11,t22) Values (:New.f1,:New.f3);
  elsif Updating Then
  Update 基本表1 set t11=:New.f1,t12=:New.f2 where t11=:New.f1;
  Update 基本表2 set t11=:New.f1,t22=:New.f3 where t11=:New.f1;
  elsif Deleting then
  Delete from 基本表1 where t11=:Old.f1;
  Delete from 基本表2 where t11=:Old.f1;









怎样在视图上建立触发器,在视图数据改动后,触发某一动作?
About MATERIALIZED VIEW:
http://download.oracle.com/docs/cd/B10500_01/server.920/a96567/repmview.htm#26164
http://download.oracle.com/docs/cd/B19306_01/server.102/b14200/statements_6002.htm
http://www.databasejournal.com/features/oracle/article.php/2192071/Materialized-Views-in-Oracle.htm
http://blog.csdn.net/XIAOHUI_LIAO/archive/2007/08/27/1759990.aspx
About MATERIALIZED VIEW LOG:
http://download.oracle.com/docs/cd/B12037_01/server.101/b10759/statements_6003.htm#i2064649
物化视图:
http://yangtingkun.itpub.net/post/468/11356(这个博客有多篇关于物化视图的资料,搜索其"物化视图")
ITPUB知识索引贴——物化视图:
http://www.itpub.net/thread-1308625-2-1.html
引用

Oracle经过长时间的发展,很多用户都很了解Oracle物化视图了,这里我发表一下个人理解,和大家讨论讨论。Oracle物化视图提供了强大的功能,可以用于预先计算并保存表连接或聚集等耗时较多的操作的结果,这样,在执行查询时,就可以避免进行这些耗时的操作,而从快速的得到结果。

Oracle物化视图有很多方面和索引很相似:使用物化视图的目的是为了提高查询性能;物化视图对应用透明,增加和删除物化视图不会影响应用程序中SQL语句的正确性和有效性;物化视图需要占用存储空间;当基表发生变化时,物化视图也应当刷新。

Oracle物化视图可以分为以下三种类型:包含聚集的物化视图;只包含连接的物化视图;嵌套物化视图。三种物化视图的快速刷新的限制条件有很大区别,而对于其他方面则区别不大。创建物化视图时可以指定多种选项,下面对几种主要的选择进行简单说明:

创建方式(Build Methods):包括BUILD IMMEDIATE和BUILD DEFERRED两种。BUILD IMMEDIATE是在创建物化视图的时候就生成数据,而BUILD DEFERRED则在创建时不生成数据,以后根据需要在生成数据。默认为BUILD IMMEDIATE。

查询重写(Query Rewrite):包括ENABLE QUERY REWRITE和DISABLE QUERY REWRITE两种。分别指出创建的物化视图是否支持查询重写。查询重写是指当对物化视图的基表进行查询时,Oracle会自动判断能否通过查询物化视图来得到结果,如果可以,则避免了聚集或连接操作,而直接从已经计算好的物化视图中读取数据。默认为DISABLE QUERY REWRITE。

刷新(Refresh):指当基表发生了DML操作后,物化视图何时采用哪种方式和基表进行同步。刷新的模式有两种:ON DEMAND和ON COMMIT。ON DEMAND指物化视图在用户需要的时候进行刷新,可以手工通过DBMS_MVIEW.REFRESH等方法来进行刷新,也可以通过JOB定时进行刷新。 ON COMMIT指出物化视图在对基表的DML操作提交的同时进行刷新。刷新的方法有四种:FAST、COMPLETE、FORCE和NEVE*。**ST刷新采用增量刷新,只刷新自上次刷新以后进行的修改。COMPLETE刷新对整个物化视图进行完全的刷新。如果选择FORCE方式,则Oracle在刷新时会去判断是否可以进行快速刷新,如果可以则采用FAST方式,否则采用COMPLETE的方式。NEVER指物化视图不进行任何刷新。默认值是FORCE ON DEMAND。

在建立物化视图的时候可以指定ORDER BY语句,使生成的数据按照一定的顺序进行保存。不过这个语句不会写入Oracle物化视图的定义中,而且对以后的刷新也无效。

物化视图创建:
引用

CREATE MATERIALIZED VIEW MV_NAME [ON PREBUILT TABLE]
[TABLESPACE TABLESPACE_NAME]
[BUILD IMMEDIATE | DEFERRED]
[REFRESH [FAST | COMPLETE | FORCE]
           [ON DEMAND | COMMIT]
           [START WITH DATE]
           [NEXT DATE]
           [WITH PRIMARY KEY | ROWID]]
[ENABLE QUERY REWRITE | DISABLE QUERY REWRITE]
AS
SELECT CLAUSE ;

建立物化视图所需权限:
http://blog.itpub.net/post/468/50672
http://blog.itpub.net/post/468/50707
http://blog.itpub.net/post/468/50838
http://blog.itpub.net/post/468/51163

关于物化视图的快速刷新:
物化视图的快速刷新(一) http://yangtingkun.itpub.net/post/468/14245
物化视图的快速刷新(二) http://yangtingkun.itpub.net/post/468/16456
物化视图的快速刷新(三) http://yangtingkun.itpub.net/post/468/16496
包含不同表字段合并的快速刷新物化视图 http://yangtingkun.itpub.net/post/468/501293
定位导致物化视图无法快速刷新的原因 http://yangtingkun.itpub.net/post/468/13318


物化视图来自多个基表连接的时候:
不能够使用标准的join...on语法,而只能够使用将连接条件放在where里的方式
http://stackoverflow.com/questions/1312980/oracle-materialized-view-not-working-when-using-left-join
为基表建立的物化视图日志,只能是基于ROWID的,且FROM语句列表中所有基表的ROWID必须出现在SELECT语句的列表中。


创建测试例子见附件!


关于MLOG$_<table_name>:
You have noticed that your fast refreshes are becoming slower and slower and
less efficient as time goes on;Can an index be created on MLOG$ (SNAPSHOT LOG)?

http://xsb.itpub.net/post/419/50466
引用

Can an index be created on MLOG$ (SNAPSHOT LOG)?
================================================

You have noticed that your fast refreshes are becoming slower and slower and
less efficient as time goes on. You want to add an index on the MLOG$ snapshot
log table to speed up the refreshes and to prevent a Full Table Scan on the
snapshot log.

First of all, the answer is NOT to add an index on the snapshot log table. 
Oracle has to do a full table scan on the snapshot log so that it can read all
the rows that it needs to refresh for a particular snapshot. Besides, all SQL
statements generated by the refresh operation is hardcoded in the kernel. 

What may be causing the performance degradation is that your snapshot log's
High Water Mark (HWM) may be wastefully high.  The snapshot log table grows at
peak times, but never shrinks once the refresh is done.  Therefore, during a
fast refresh of the snapshot, Oracle will read the snapshot log using full
table scan all the way to the HWM.

The answer to speeding up the performance of the snapshot refresh is to reset
the HWM.  The only way to do this is to truncate the snapshot log or recreate
it. 

Once your snapshot log is purged (meaning all snapshots have already refreshed
against that master table), then issue a truncate on it.

i.e.  SQL> truncate table mlog$_EMP;
     
This will reset the HWM without affecting any of your snapshot's fast refreshes. 

If you choose to RECREATE your snapshot log, you will have to follow up by
performing a COMPLETE refresh on all the affected snapshots.


关于RUPD$_<table_name>:
The mlogs$_<table_name> is the materialized view log created with the CREATE MATERIALIZED VIEW LOG command.  Note that materialized view log tables using primary keys also have rupd$_ tables.  The rupd$_ table supports updateable materialized views , which are only possible on log tables with primary keys.
http://www.dbasupport.com/forums/showthread.php?t=54919
http://www.dbasupport.com/forums/showthread.php?t=41349

你可能感兴趣的:(oracle,sql,.net,PHP,SQL Server)