我受entity-attribute-value antipattern的打击。有一天,几年前,一个人认为DDL不性感,并希望开发一些“足够灵活”来保存人们的信息。他忽略了人们使用至少一些基本属性的事实,如姓名,出生日期等。不仅如此,他还在该架构之上放置了一堆(副作用缠绕的)PL / SQL包。这件事成了其他应用程序所依赖的关键子系统。
快进几年和2000万行。这家伙不再在公司了,我必须处理这件事。我需要实现一些基本的搜索,现在需要多个内部连接,并且在某些情况下需要永远。重写整个事情是不可能的,所以我想“转动”最重要的属性。
我认为物化观点可能是一种可行的选择,但我需要一些指导,因为我从未使用它们。我想得到一张这样的表:
select
uid,
max(case when att = 'NAME' then UPPER(value) end) name,
max(case when att = 'SURNAME' then UPPER(value) end) surname,
max(case when att = 'BIRTH' then DATEORNULL(value) end) birth,
....,
count(*) cnt
from t
group by uid
据我所知阅读Oracle文档,我应该能够使用MAX()if the query has no where clause创建一个“REFRESHABLE ON COMMIT”物化视图。
但无法让它发挥作用。我试过了:
create materialized view log on t WITH SEQUENCE,ROWID,(value) INCLUDING NEW VALUES;
create materialized view t_view
refresh fast on commit
as
select
uid,
max(case when att = 'NAME' then UPPER(value) end) name,
max(case when att = 'SURNAME' then UPPER(value) end) surname,
max(case when att = 'BIRTH' then DATEORNULL(value) end) birth,
count(*) cnt
from t
group by uid
适用于插入,但不适用于更新。我看到它能够做到这些:
REFRESH_COMPLETE
REFRESH_FAST
REFRESH_FAST_AFTER_INSERT
但我想我也应该看到REFRESH_FAST_AFTER_ONETAB_DML。有什么想法吗?
更新:输出dbms_mview.explain_mview
REFRESH_COMPLETE |Y|
REFRESH_FAST |Y|
REFRESH_FAST_AFTER_INSERT |Y|
REFRESH_FAST_AFTER_ONETAB_DML|N|mv uses the MIN or MAX aggregate functions
REFRESH_FAST_AFTER_ANY_DML |N|see the reason why REFRESH_FAST_AFTER_ONETAB_DML is disabled
REFRESH_FAST_PCT |N|PCT is not possible on any of the detail tables in the mater
答案 0 :(得分:2)
MV_CAPABILITIES_TABLE.MSGTXT
错误,您真正需要做的是将case
替换为decode
。
当我在11g上尝试这个时,我得到了消息CASE expressions present in materialized view
。将其更改为使用decode
将其固定在10g和11g上。