Kar*_*run 5 oracle materialized-views
我将物化视图设置为REFRESH FAST ON COMMIT.源表中有4个BLOB列,我将转换为VARCHAR2作为MV的一部分:
CREATE MATERIALIZED VIEW Employee_MV
REFRESH FAST ON COMMIT
WITH PRIMARY KEY
AS
SELECT UTL_RAW.CAST_TO_VARCHAR2(DBMS_LOB.SUBSTR (History, 2000, 1)), //BLOB column
<3 more blob columns with similar conversions>,
<misc columns from different tables>,
<rowid columns for tables for REFRESH FAST to work>
FROM <list of tables with JOINs>
Run Code Online (Sandbox Code Playgroud)
如果在使用BLOB列的参与表中插入行时刷新MV - 无论是通过ON COMMIT还是ON DEMAND - 它会出现以下消息错误:
ORA-12008: error in materialized view refresh path
ORA-06553: PLS-307: too many declarations of 'SUBSTR' match this call
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 2545
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 2751
ORA-06512: at "SYS.DBMS_SNAPSHOT", line 2720
ORA-06512: at line 1
Run Code Online (Sandbox Code Playgroud)
令我感到困惑的是,错误发生在"DBMS_LOB.SUBSTR"调用中.(这是我在这个MV中使用SUBSTR的唯一地方,如果我删除BLOB转换,MV会刷新而不会出错.)
这是否意味着Oracle无法解析为正确的重载版本(CLOB,BLOB和BFILE各有一个SUBSTR)?但这没有意义,因为如果我单独运行这个MV的SELECT查询它运行得很好.
我在这里错过了什么?
更新:我尝试使用REFRESH COMPLETE选项刷新MV,并使用相同的数据.所以现在我的情况是SUBSTR()仅在FAST刷新时失败,但适用于COMPLETE刷新.
更新2:当前的Oracle版本是11.1.0.7.我尝试在Oracle 10.2.0.4(不同的环境)中运行相同的MV.MV完成了FAST REFRESH,没有任何问题.
因此,DBMS_LOB.SUBSTR处理BLOB存在一些问题,例如:
我该如何进一步排除故障?
更新3:我刚刚运行了一些测试来检查BLOB列中是否存在NULL这样的行为 - 事实证明即使使用非空值,MV FAST REFRESH也会失败并出现相同的错误.我已相应更新了这个问题.
如果 Oracle 不允许您在该 mv 中运行多次“substr”函数 - 做一些技巧来欺骗他;)您可以在快速刷新之前使用虚拟列进行此“substr”调用,如下所示:
alter table YOUR_TABLE add History_substr as (DBMS_LOB.SUBSTR (History,2000, 1)) virtual;
Run Code Online (Sandbox Code Playgroud)
如上所述,在这里执行其他“具有类似转换的另外 3 个 blob 列”,然后您可以使用虚拟列:
CREATE MATERIALIZED VIEW Employee_MV
REFRESH FAST ON COMMIT
WITH PRIMARY KEY
AS
SELECT UTL_RAW.CAST_TO_VARCHAR2(History_substr), //BLOB column
<3 more blob columns with similar conversions>,
<misc columns from different tables>,
<rowid columns for tables for REFRESH FAST to work>
FROM <list of tables with JOINs>
Run Code Online (Sandbox Code Playgroud)