我在Oracle中有几个物化视图,我可以查询以获取信息。
现在我想创建几个带有引用这些MV的外键的表,并且这样做,我已经"添加了" MV的相应主键(如adding primary key to sql view中所述)。
然后,当我执行我的SQL 创建表查询时,我得到一个 Oracle(ORA-02270)错误:此列列表错误没有匹配的唯一或主键在第0位,在开头......
我做错了吗?有可能我想做什么? 如果没有,通常如何做?
答案 0 :(得分:0)
查看约束
Oracle 不强制执行视图约束。但是,操作上 视图受到定义的完整性约束 底层基表。这意味着您可以强制执行约束 通过对基表的约束来查看。
还有:
视图约束是表约束的一个子集,并受其约束 以下限制:
- ...
- 仅在DISABLE NOVALIDATE模式中支持视图约束。您无法指定任何其他模式。您必须指定关键字DISABLE 当您声明视图约束时。您无需指定NOVALIDATE 显式,因为它是默认值。
- ...
在实践中,上述意味着虽然可以创建视图约束,但它们被阻止且不起作用。好像他们根本就没有。
除此之外,想一想在表上创建外键约束的意义是什么,这将引用物化视图:
想象一下这种情况:您将记录X插入某个表中。此记录在物化视图中不可见,因为此时视图未刷新。然后,您尝试将记录X插入另一个具有指向该物化视图的外键约束的表中。数据库应该做什么?数据库是否应该拒绝insert语句(因为现在X在视图中是不可见的并且外键存在)?如果是,那么数据完整性呢? Mayby是否应该阻止amd等待视图刷新?在这种情况下是否应该强制视图开始刷新?
正如您所看到的,这种情况涉及实现中的许多问题和难题,因此Oracle根本不允许对视图进行约束。
答案 1 :(得分:0)
当有其他表的外键引用的物化视图时,您必须注意视图刷新方法及其对外键的影响。 有两件事可能会阻止您刷新实例化视图:
1)引用您的视图的表中的数据可能引用了需要更新或删除的行。在这种情况下,您必须修复数据。
2)您的视图的刷新方法已完成。在完全刷新中,Oracle会删除您的mviews表中的所有数据,并通过重新运行它们的查询来填充它们,如在Oracle site documentation - Refresh Types中所见,而在快速刷新中,只有差异会应用于您的mviews表。快速刷新是一种增量刷新,只有在您的数据不遵守外键的情况下,它才起作用。
现在,如果无法通过快速刷新创建mview(Oracle将其称为“复杂查询”),则可以将对这些mview的约束更改为可延迟,如您所见here。
这样一来,即使是完全刷新也将起作用,因为Oracle仅在当前事务结束之前验证可延迟约束。因此,只要您的刷新方法是原子的,Oracle就会发出DELETE,然后在一次事务中将所有行都插入回去。
换句话说,在下一个刷新mview的命令中,将参数atomic_refresh保持为true:
dbms_mview.refresh(LIST=>'MVIEW', METHOD =>'C', ATOMIC_REFRESH => TRUE);
顺便说一句,此参数的默认值为TRUE,所以不要提及它,它将起作用。