【问题标题】:ORACLE : Materialized view not working when Using LEFT JOINORACLE:使用 LEFT JOIN 时物化视图不起作用
【发布时间】:2010-11-21 17:30:06
【问题描述】:

我想从 2 个表的 LEFT JOIN 创建一个 MATERIALIZED VIEW。但是以下给了我一个错误:

    SELECT field1 
     FROM table_1 a 
     LEFT JOIN table_2 b 
     ON a.field1=b.field2

ORA-12054: 无法为实体化视图设置 ON COMMIT 刷新属性

但是以下工作:

SELECT field1 
 FROM table_1 a, table_2 b 
 WHERE a.field1=b.field2

有没有人知道为什么会发生这种情况。

感谢帮助

【问题讨论】:

    标签: oracle views join materialized


    【解决方案1】:

    由于这是一篇旧帖子;没有提到完整的解决方案。

    1. 外部联接的表应具有 Oracle 文档中提到的主键。
    2. 查询不应有任何其他约束,即不应有任何过滤条件 在WHERE 子句中,只是连接;在SELECT 子句中也不能有CASE/DECODE 语句;不过,GROUP BYSUM()COUNT() 等都是允许的。

    在上面的示例中,如果在 dept id 列的部门表上创建主键,则查询将起作用。

    【讨论】:

    • “WHERE 子句中不应该有任何过滤条件,只有连接” 你能支持这一点吗?
    【解决方案2】:

    要使物化视图快速刷新,有两个条件不满足。第一个是您没有指定所涉及的每个表的 rowid 列。第二个是未记录的限制:不支持 ANSI 连接。

    这是一个示例,DEPT 为 table_1,别名 a,EMP 为 table_2,别名 b:

    SQL> create materialized view log on emp with rowid
      2  /
    
    Materialized view log created.
    
    SQL> create materialized view log on dept with rowid
      2  /
    
    Materialized view log created.
    
    SQL> create materialized view empdept_mv
      2    refresh fast on commit
      3  as
      4  select a.deptno
      5    from dept a
      6         left join emp b on (a.deptno = b.deptno)
      7  /
      from dept a
           *
    ERROR at line 5:
    ORA-12054: cannot set the ON COMMIT refresh attribute for the materialized view
    

    这模仿了你的情况。首先添加rowid的:

    SQL> create materialized view empdept_mv
      2    refresh fast on commit
      3  as
      4  select a.rowid dept_rowid
      5       , b.rowid emp_rowid
      6       , a.deptno
      7    from dept a
      8         left join emp b on (a.deptno = b.deptno)
      9  /
      from dept a
           *
    ERROR at line 7:
    ORA-12054: cannot set the ON COMMIT refresh attribute for the materialized view
    

    由于 ANSI 连接,它仍然无法快速刷新。转换为旧式外连接语法:

    SQL> create materialized view empdept_mv
      2    refresh fast on commit
      3  as
      4  select a.rowid dept_rowid
      5       , b.rowid emp_rowid
      6       , a.deptno
      7    from dept a
      8       , emp b
      9   where a.deptno = b.deptno (+)
     10  /
    
    Materialized view created.
    

    并证明它有效:

    SQL> select * from empdept_mv
      2  /
    
    DEPT_ROWID         EMP_ROWID              DEPTNO
    ------------------ ------------------ ----------
    AAARhmAAEAAAAI/AAB AAARhlAAEAAAAI3AAA         20
    AAARhmAAEAAAAI/AAC AAARhlAAEAAAAI3AAB         30
    AAARhmAAEAAAAI/AAC AAARhlAAEAAAAI3AAC         30
    AAARhmAAEAAAAI/AAB AAARhlAAEAAAAI3AAD         20
    AAARhmAAEAAAAI/AAC AAARhlAAEAAAAI3AAE         30
    AAARhmAAEAAAAI/AAC AAARhlAAEAAAAI3AAF         30
    AAARhmAAEAAAAI/AAA AAARhlAAEAAAAI3AAG         10
    AAARhmAAEAAAAI/AAB AAARhlAAEAAAAI3AAH         20
    AAARhmAAEAAAAI/AAA AAARhlAAEAAAAI3AAI         10
    AAARhmAAEAAAAI/AAC AAARhlAAEAAAAI3AAJ         30
    AAARhmAAEAAAAI/AAB AAARhlAAEAAAAI3AAK         20
    AAARhmAAEAAAAI/AAC AAARhlAAEAAAAI3AAL         30
    AAARhmAAEAAAAI/AAB AAARhlAAEAAAAI3AAM         20
    AAARhmAAEAAAAI/AAA AAARhlAAEAAAAI3AAN         10
    AAARhmAAEAAAAI/AAD                            40
    
    15 rows selected.
    
    SQL> insert into dept values (50,'IT','UTRECHT')
      2  /
    
    1 row created.
    
    SQL> commit
      2  /
    
    Commit complete.
    
    SQL> select * from empdept_mv
      2  /
    
    DEPT_ROWID         EMP_ROWID              DEPTNO
    ------------------ ------------------ ----------
    AAARhmAAEAAAAI/AAB AAARhlAAEAAAAI3AAA         20
    AAARhmAAEAAAAI/AAC AAARhlAAEAAAAI3AAB         30
    AAARhmAAEAAAAI/AAC AAARhlAAEAAAAI3AAC         30
    AAARhmAAEAAAAI/AAB AAARhlAAEAAAAI3AAD         20
    AAARhmAAEAAAAI/AAC AAARhlAAEAAAAI3AAE         30
    AAARhmAAEAAAAI/AAC AAARhlAAEAAAAI3AAF         30
    AAARhmAAEAAAAI/AAA AAARhlAAEAAAAI3AAG         10
    AAARhmAAEAAAAI/AAB AAARhlAAEAAAAI3AAH         20
    AAARhmAAEAAAAI/AAA AAARhlAAEAAAAI3AAI         10
    AAARhmAAEAAAAI/AAC AAARhlAAEAAAAI3AAJ         30
    AAARhmAAEAAAAI/AAB AAARhlAAEAAAAI3AAK         20
    AAARhmAAEAAAAI/AAC AAARhlAAEAAAAI3AAL         30
    AAARhmAAEAAAAI/AAB AAARhlAAEAAAAI3AAM         20
    AAARhmAAEAAAAI/AAA AAARhlAAEAAAAI3AAN         10
    AAARhmAAEAAAAI/AAD                            40
    AAARhmAAEAAAAI7AAA                            50
    
    16 rows selected.
    

    this blogpost 的第 6 点提到了 ANSI 连接语法限制。

    问候, 抢。

    【讨论】:

    • 非常感谢罗。这非常有帮助:) 虽然我必须使用旧样式进行左连接(将不得不重写许多视图和查询),但这让我很恼火。丹
    • 不敢相信 Oracle 还没有实现 ANSI JOIN 支持。谢谢你
    【解决方案3】:

    按照以下说明使 DBMS_MVIEW.EXPLAIN_MVIEW 工作: http://www.sqlsnippets.com/en/topic-12884.html

    能够:

    REFRESH_COMPLETE

    没有能力:

    REFRESH_FAST

    REFRESH_FAST_AFTER_INSERT
    此类型 MV 不支持 FROM 列表中的内联视图或子查询

    REFRESH_FAST_AFTER_INSERT
    此类型 MV 不支持 FROM 列表中的内联视图或子查询

    REFRESH_FAST_AFTER_INSERT
    从列表中查看或子查询

    REFRESH_FAST_AFTER_ONETAB_DML
    查看 REFRESH_FAST_AFTER_INSERT 被禁用的原因

    MV_REPORT

    REFRESH_FAST_AFTER_ANY_DML
    查看 REFRESH_FAST_AFTER_ONETAB_DML 被禁用的原因

    【讨论】:

      猜你喜欢
      • 2018-11-01
      • 2013-06-15
      • 2015-12-05
      • 2016-12-09
      • 1970-01-01
      • 1970-01-01
      • 2018-11-30
      • 2013-09-14
      • 1970-01-01
      相关资源
      最近更新 更多