2

我有两个表“调查”和“调查处理”,两者基本上都是相似的表。我有一个工作查询,它​​在两个表之间使用 UNION ALL 运算符并得到一些计数。当我尝试将其转换为物化视图时,我收到与 ON COMMIT 相关的错误。查看下面的 MV DDL 和错误。

    创建物化视图 vwm_survey_records_count
    提交时快速刷新
    作为
    选择
        survey_combined.survey_header_id,
        COUNT(*) AS count_total,
        计数(CASE WHENsurvey_combined.processed_flag = 'Y' THEN 1 ELSE NULL END)AS count_a,
        计数(CASE WHENsurvey_combined.approved_flag 为 NULL THEN 1 ELSE NULL END)作为 count_b,
        计数(CASE WHENsurvey_combined.processed_flag = 'N' ANDsurvey_combined.approved_flag = 'Y' THEN 1 ELSE NULL END)AS count_c,
        计数(CASE WHENsurvey_combined.approved_flag = 'N' THEN 1 ELSE NULL END)AS count_d
    从
    (
    从调查中选择survey_header_id、'N' AS processes_flag、approved_flag
    联合所有
    选择survey_header_id,'Y' AS processes_flag,approved_flag FROMsurvey_processed)survey_combined
    INNER JOINsurvey_header ONsurvey_combined.survey_header_id =survey_header.id
    GROUP BYsurvey_combined.survey_header_id;

如果我运行上述命令,则会出现错误:
'SQL 错误:ORA-12054:无法为物化视图设置 ON COMMIT 刷新属性'。

但是,如果我使用“按需刷新完成”,它就可以工作。我知道显然打破了 ON COMMIT 属性的一些限制,但不知道是哪个。有人可以让我知道上述查询做错了什么吗?此外,在创建 MV 时,是否有任何更好的查询方法可以使其高效并使用“REFRESH FAST ON COMMIT”。

注意:我在所选列上使用 rowid 为两个表创建了 MV 日志。
如果有人有任何问题,请告诉我。

提前致谢。

这是 'jonearles' 要求的 MV 日志的 DDL

    使用序列、ROWID(id、survey_header_id、approved_flag、processed_flag)创建包括新值的调查的实体化视图日志;
    使用序列、ROWID(id、survey_header_id、approved_flag)在survey_processed上创建实体化视图日志,包括新值;
    在带有序列,ROWID(id)包括新值的survey_header上创建物化视图日志;

注意:稍后将删除“survey”表中的“processed_flag”列。从技术上讲,这两个表最近根据“processed_flag”列的值进行了拆分。因此,“调查”表具有所有未处理的记录(processed_flag = 'N'),而“survey_processed”具有已处理的记录(processed_flag = 'Y')。拆分后,该列无关紧要。

4

1 回答 1

3

我认为你在这里不走运。从使用 UNION ALL 对物化视图进行快速刷新的限制

定义查询的顶层必须有 UNION ALL 运算符。

并且用UNION ALL外部连接替换也不起作用。聚合和外部连接似乎不能一起工作。下面的代码与您的代码不等价,但它表明即使是您的查询的简化版本也不起作用:

CREATE MATERIALIZED VIEW vwm_survey_records_count
REFRESH COMPLETE ON DEMAND AS
SELECT survey_header.id AS survey_header_id, COUNT(*) AS count_total
FROM survey_header, survey, survey_processed
WHERE survey_header.id = survey.survey_header_id(+)
GROUP BY survey_header.id;


delete from MV_CAPABILITIES_TABLE;
begin
    DBMS_MVIEW.EXPLAIN_MVIEW ('VWM_SURVEY_RECORDS_COUNT');
end;
/
select possible, msgno, msgtxt
from MV_CAPABILITIES_TABLE
where capability_name = 'REFRESH_FAST_AFTER_INSERT';

POSSIBLE    MSGNO   MSGTXT
--------    -----   ------
N           2048    outer join in mv
于 2013-07-12T05:14:12.367 回答