13

当我在 Oracle 10g 上运行以下代码时:

drop materialized view test4;
drop materialized view test3;
drop table test2;
drop table test1;

create table test1
(
  x1 varchar2(1000),
  constraint test1_pk primary key (x1)
);

create materialized view log on test1 with sequence;

create table test2
(
  x2 varchar2(1000),
  constraint test2_pk primary key (x2)
);

create materialized view log on test2 with sequence;

create materialized view test3
refresh complete on demand 
as
(
  select x1 from test1
  union all
  select null from dual where 0 = 1
);

alter table test3 add constraint test3_pk primary key (x1);

create materialized view log on test3 with sequence;

create materialized view test4
refresh fast on commit
as
(
  select t1.rowid as rid1, t2.rowid as rid2, t1.x1 u1, t2.x2
  from test3 t1, test2 t2
  where t1.x1 = t2.x2
);

尝试创建物化视图时出现此错误test4

SQL Error: ORA-12053: this is not a valid nested materialized view  
12053. 00000 -  "this is not a valid nested materialized view"  
*Cause:    The list of objects in the FROM clause of the definition of this  
           materialized view had some dependencies upon each other.  
*Action:   Refer to the documentation to see which types of nesting are valid.

我不明白“FROM 子句”中的任何对象如何相互依赖。

我怎样才能让它工作?目前我能想到的唯一解决方法是test3用普通表替换并手动删除和刷新数据。这种方法有效,但似乎有点 hack。

或者(也许最好)我只想看一个示例,其中可以有两个表,并将它们加入一个物化视图,其中一个基表是批量更新的(并且不需要反映在物化视图中) 但其他更新应该反映在物化视图中(即它是一种 "half"fast refresh on commit和 half complete refresh on demand)。我尝试使用refresh force,但是在使用时EXECUTE DBMS_MVIEW.EXPLAIN_MVIEW()我发现没有证据表明提交时刷新刷新可用。我也想用union alls 来做这件事。

4

3 回答 3

3

您可以像这样使 test4 物化视图快速刷新:

SQL> create table test1
  2  ( x1 varchar2(1000)
  3  , constraint test1_pk primary key (x1)
  4  )
  5  /

Table created.

SQL> create materialized view log on test1 with rowid
  2  /

Materialized view log created.

SQL> create table test2
  2  ( x2 varchar2(1000)
  3  , constraint test2_pk primary key (x2)
  4  )
  5  /

Table created.

SQL> create materialized view log on test2 with rowid
  2  /

Materialized view log created.

SQL> create materialized view test4
  2  refresh fast on commit
  3  as
  4    select t1.rowid as rid1
  5         , t2.rowid as rid2
  6         , t1.x1 u1
  7         , t2.x2
  8      from test1 t1
  9         , test2 t2
 10     where t1.x1 = t2.x2
 11  /

Materialized view created.

SQL> insert into test1 values ('hello')
  2  /

1 row created.

SQL> insert into test2 values ('hello')
  2  /

1 row created.

SQL> commit
  2  /

Commit complete.

SQL> select * from test4
  2  /

RID1               RID2
------------------ ------------------
U1
---------------------------------------------
X2
---------------------------------------------
AAATU5AAEAAAssfAAA AAATU8AAEAAAssvAAA
hello
hello


1 row selected.

您的情况不起作用,因为要使嵌套 MV 起作用,基础 MV 不能是基本 MV。起初这听起来很奇怪,但您需要像使用 test3 一样的技巧才能使其工作。此外,要使连接 MV 起作用,需要使用 ROWID 创建基础表的物化视图日志。

您可能想查看我写的关于快速可刷新物化视图错误的一系列博客文章。它们描述了几乎所有的限制:

Basic MV's
Join MV's
Aggregate MV's
Union all MV's
Nested MV's
MV_CAPABILITIES_TABLE
Summary

问候,
罗布。


添加:2011 年 9 月 29 日

这是一个嵌套 MV 的示例,它也在 test2 上使用了 union all 技巧:

SQL> create table test1
  2  ( x1 varchar2(1000)
  3  , constraint test1_pk primary key (x1)
  4  )
  5  /

Table created.

SQL> create materialized view log on test1 with rowid
  2  /

Materialized view log created.

SQL> create table test2
  2  ( x2 varchar2(1000)
  3  , constraint test2_pk primary key (x2)
  4  )
  5  /

Table created.

SQL> create materialized view log on test2 with rowid
  2  /

Materialized view log created.

SQL> create materialized view test2_mv
  2  refresh fast on commit
  3  as
  4  select rowid rid
  5       , x2
  6       , 'A' umarker
  7    from test2
  8   union all
  9  select rowid
 10       , x2
 11       , 'B'
 12    from test2
 13   where 1=0
 14  /

Materialized view created.

SQL> alter table test2_mv add constraint test2_mv_pk primary key(x2)
  2  /

Table altered.

SQL> create materialized view log on test2_mv with rowid
  2  /

Materialized view log created.

SQL> create materialized view test3
  2  refresh fast on commit
  3  as
  4  select rowid rid
  5       , x1
  6       , 'A' umarker
  7    from test1
  8   union all
  9  select rowid
 10       , x1
 11       , 'B'
 12    from test1
 13   where 0 = 1
 14  /

Materialized view created.

SQL> alter table test3 add constraint test3_pk primary key (x1)
  2  /

Table altered.

SQL> create materialized view log on test3 with rowid
  2  /

Materialized view log created.

SQL> create materialized view test4
  2  refresh fast on commit
  3  as
  4    select t1.rowid as rid1
  5         , t2.rowid as rid2
  6         , t1.x1 u1
  7         , t2.x2
  8      from test3 t1
  9         , test2_mv t2
 10     where t1.x1 = t2.x2
 11  /

Materialized view created.

SQL> insert into test1 values ('hello')
  2  /

1 row created.

SQL> insert into test2 values ('hello')
  2  /

1 row created.

SQL> commit
  2  /

Commit complete.

SQL> select * from test4
  2  /

RID1               RID2
------------------ ------------------
U1
---------------------------------------------------
X2
---------------------------------------------------
AAATXbAAEAAAstdAAA AAATXXAAEAAAstNAAA
hello
hello


1 row selected.

希望这可以帮助!

于 2011-09-26T17:24:54.330 回答
2

来自Oracle的报价

使用多层实体化视图的限制

主物化视图和基于物化视图的物化视图都必须:

  • 成为主键物化视图
  • 驻留在 9.0.1 或更高兼容级别的数据库中

注意:COMPATIBLE 初始化参数控制数据库的兼容性级别。

但是,我会为您尝试解决方案。我会回来的。

更新:对不起,我没有成功。你有太多的限制:)

于 2011-09-20T06:54:09.927 回答
0

根据 Oracle 文档,您可能不走运:

http://download.oracle.com/docs/cd/B28359_01/server.111/b28313/basicmv.htm#i1006734

您可以在实体化视图上创建嵌套实体化视图,但所有父实体化视图和基础实体化视图都必须包含连接或聚合。如果物化视图的定义查询不包含连接或聚合,则不能嵌套。定义了物化视图的所有底层对象(物化视图或表)都必须具有物化视图日志。所有基础对象都被视为表。此外,您可以将所有现有选项用于物化视图。

于 2011-09-26T15:14:57.683 回答