【问题标题】:Materialized View - FAST refresh not able to create due to complex query物化视图 - 由于复杂的查询,无法创建快速刷新
【发布时间】:2020-05-04 20:30:59
【问题描述】:

我们正在处理刷新 FORCE 或 COMPLETE 时成功创建的物化视图,但刷新 FAST 时它不会创建 MV。错误总是“定义中缺少某些表的 ROWID,或者外部连接的内部表在连接列上没有 UNIQUE 约束。”或“复杂查询既不支持 ROWID 也不支持主键约束。”

下面是查询-

-- MATERIALIZED VIEW log for A

CREATE MATERIALIZED VIEW LOG ON SCHEMA.A
TABLESPACE A_SCHEMA_DATA
WITH PRIMARY KEY
INCLUDING NEW VALUES;

-- MATERIALIZED VIEW log for B
CREATE MATERIALIZED VIEW LOG ON A_SCHEMA.B
TABLESPACE A_SCHEMA_DATA 
WITH PRIMARY KEY
INCLUDING NEW VALUES;


-- MATERIALIZED VIEW Query
CREATE MATERIALIZED VIEW A_SCHEMA.MV_A1
BUILD IMMEDIATE 
REFRESH FAST ON DEMAND
AS 

  SELECT * FROM (
   SELECT 
        A.T_ID,
        B.NAME AS NAME,
        B.ANS AS ANS
   FROM A_SCHEMA.A A, A_SCHEMA.B B
   WHERE A.T_ID = B.T_ID AND 
   B.NAME IN ('Order', 'Price')
 )
 PIVOT
 (
   MAX(to_char(SUBSTR(ANS, 0,100)))
   FOR NAME IN ('Order' ORDER, 'Price' PRICE)
 )
ORDER BY A.CREATED_DATE BY DESC;

【问题讨论】:

    标签: oracle view oracle11g pivot-table


    【解决方案1】:

    使用MAX(DECODE... 而不是PIVOT 来解决错误“ORA-12015: cannot create a fast refresh materialized view from a complex query”。

    快速刷新物化视图经常需要使用旧版本的功能,并且查询通常会看起来很丑陋。例如,我们必须使用老式的(+) 连接语法而不是 ANSI 连接。 PIVOT 不好,甚至 MAX(CASE WHEN... 模式在 11g 中也不起作用。您还需要向物化视图日志添加一些设置,如下所述。

    示例架构

    --drop table a;
    --drop table b;
    --drop materialized view mv_a1;
    
    create table a(t_id number primary key);
    create materialized view log on a with sequence,rowid(t_id) including new values;
    
    create table b(t_id number, name varchar2(100), ans varchar2(100));
    create materialized view log on b with sequence,rowid(t_id,name,ans) including new values;
    
    insert into a values(1);
    insert into a values(2);
    insert into b values(1, 'Order', 'A');
    insert into b values(2, 'Price', 'A');
    insert into b values(2, 'Price', 'B');
    

    物化视图

    create materialized view mv_a1
    build immediate 
    refresh fast on commit
    AS 
    select
        a.t_id,
        max(decode(name, 'Order', to_char(substr(ans, 0,100)))) the_order,
        max(decode(name, 'Price', to_char(substr(ans, 0,100)))) price
        --In old versions (11g and below?), extra COUNTs were necessary.
        --See: https://docs.oracle.com/cd/E11882_01/server.112/e25554/basicmv.htm#DWHSG0082
        ,count(*) the_count, count(a.t_id) count_t_id, count(name) count_name, count(ans) count_ans
    from a, b
    where a.t_id = b.t_id
    group by a.t_id;
    

    【讨论】:

    • 您好乔恩,谢谢回复,我尝试了您的查询,但它不起作用,我仍然收到“定义中缺少某些表的 ROWID 或外部连接的内部表没有连接列上没有 UNIQUE 约束。”
    • @oraclenewbie 查看我的更新答案。以前版本的 Oracle 需要额外的 COUNT 列来实现一些快速刷新的物化视图。不幸的是,我无法访问 11g,也无法测试新代码。您可能已经意识到,快速刷新物化视图非常困难。
    猜你喜欢
    • 2018-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-27
    • 2013-06-28
    • 2013-12-04
    • 2021-11-06
    • 2012-02-18
    相关资源
    最近更新 更多