理解物化視圖刷新過程中出現的約束沖突
2024-07-21 02:32:31
供稿:網友
本文通過實例的方法來幫助您理解物化視圖刷新過程中出現的約束沖突問題。 即使將物化視圖的約束建立和基表完全一致,由于物化視圖的刷新機制,也會產生約束沖突的現象。 一個簡單的例子:
SQL> CREATE TABLE T (ID NUMBER PRIMARY KEY, NAME VARCHAR2(30));--表已創建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 (1, 'A');--已創建 1 行:SQL> INSERT INTO T VALUES (2, 'B');--已創建 1 行:SQL> COMMIT;--提交完成:SQL> EXEC DBMS_MVIEW.REFRESH('MV_T') --PL/SQL 過程已成功完成。上面構造了一個簡單的物化視圖,物化視圖和基表建立了相同的唯一約束。 下面進行一個循環的更新操作,然后觀察刷新的情況: SQL> UPDATE T SET NAME = 'C' WHERE ID = 1;--已更新 1 行。SQL> UPDATE T SET NAME = 'A' WHERE ID = 2;--已更新 1 行。SQL> UPDATE T SET NAME = 'B' WHERE ID = 1;--已更新 1 行。SQL> COMMIT;--提交完成。SQL> EXEC DBMS_MVIEW.REFRESH('MV_T')BEGIN DBMS_MVIEW.REFRESH('MV_T'); END;*ERROR 位于第 1 行:ORA-12008: 實體化視圖的刷新路徑中存在錯誤ORA-00001: 違反唯一約束條件 (YANGTK.UN_MV_T_NAME)ORA-06512: 在"SYS.DBMS_SNAPSHOT", line 794ORA-06512: 在"SYS.DBMS_SNAPSHOT", line 851ORA-06512: 在"SYS.DBMS_SNAPSHOT", line 832 ORA-06512: 在line 1刷新失敗了。解決這個問題的一個方法是對于物化視圖不建立唯一約束,唯一性由基表保證。但是這種方法只對只讀物化視圖適用。而且,缺少唯一約束信息,可能會影響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_MVIEW.REFRESH('MV_T') --PL/SQL 過程已成功完成。注重,延遲唯一約束對應的索引也必須是非唯一的,否則無法達到延遲約束的目的。