物化视图-由于复杂的查询而无法创建FAST刷新

时间:2020-05-04 20:30:59

标签: oracle view oracle11g pivot-table

我们正在处理实例化视图,该视图在刷新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;

1 个答案:

答案 0 :(得分:0)

使用MAX(DECODE...代替PIVOT来解决错误“ ORA-12015:无法通过复杂的查询创建快速刷新实例化视图”。

快速刷新实例化视图通常需要使用较早版本的功能,并且查询通常最终看起来很丑陋。例如,我们必须使用老式的(+)连接语法而不是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;