本文中我们通过实例的方法来帮助您理解物化视图刷新过程中出现的约束沖突问题 即使将物化视图的约束建立和基表完全一致由于物化视图的刷新机制也会产生约束沖突的现象 以下是一个简单的示例 SQL> CREATE TABLE T (ID NUMBER PRIMARY KEY NAME VARCHAR());表已创建SQL> ALTER TABLE T ADD CONSTRAINT UN_T_NAME UNIQUE (NAME);表已更改SQL> CREATE MATERIALIZED VIEW LOG ON T;实体化视图日志已创建SQL> CREATE MATERIALIZED VIEW MV_T REFRESH FAST AS SELECT * FROM T;实体化视图已创建SQL> ALTER TABLE MV_T ADD CONSTRAINT UN_MV_T_NAME UNIQUE (NAME);表已更改SQL> INSERT INTO T VALUES ( A);已创建 行SQL> INSERT INTO T VALUES ( B);已创建 行SQL> COMMIT;提交完成SQL> EXEC DBMS_MVIEWREFRESH(MV_T)PL/SQL 过程已成功完成 上面构造了一个简单的物化视图物化视图和基表建立了相同的唯一约束 下面进行一个循环的更新操作然后观察刷新的情况 SQL> UPDATE T SET NAME = C WHERE ID = ;已更新 行SQL> UPDATE T SET NAME = A WHERE ID = ;已更新 行SQL> UPDATE T SET NAME = B WHERE ID = ;已更新 行SQL> COMMIT;提交完成SQL> EXEC DBMS_MVIEWREFRESH(MV_T)BEGIN DBMS_MVIEWREFRESH(MV_T); END;*ERROR 位于第 行:ORA: 实体化视图的刷新路径中存在错误ORA: 违反唯一约束条件 (YANGTKUN_MV_T_NAME)ORA: 在SYSDBMS_SNAPSHOT line ORA: 在SYSDBMS_SNAPSHOT line ORA: 在SYSDBMS_SNAPSHOT line ORA: 在line 刷新失败了解决这个问题的一个方法是对于物化视图不建立唯一约束唯一性由基表保证但是这种方法只对只读物化视图适用而且缺少唯一约束信息可能会影响SQL的执行计划 这种情况下最好的解决方法是建立延迟约束 SQL> ALTER TABLE MV_T DROP CONSTRAINT UN_MV_T_NAME;表已更改SQL> ALTER TABLE MV_T ADD CONSTRAINT UN_MV_T_NAME UNIQUE (NAME) DEFERRABLE;表已更改SQL> EXEC DBMS_MVIEWREFRESH(MV_T)PL/SQL 过程已成功完成 注释延迟唯一约束对应的索引也必须是非唯一的否则无法达到延迟约束的目的 |