Oracle - 创建带有主键的视图

4

这个问题的意思已经有重复,但我仍然需要澄清。Oracle文档明确 ,可以在CREATE VIEW从句中指定主键(11g文档也有同样的说法)。但是,当我尝试像这样做时:

create or replace view ABC(A, B, C, CONSTRAINT A_PK PRIMARY KEY (A)) ....

我遇到了ORA-00922: missing or invalid option错误,指向“primary key”短语。问题是,是我的问题还是Oracle文档的问题?

2个回答

12
简单的答案是你的语法不正确。你必须指定DISABLENOVALIDATE会禁用主键验证,在视图中这是默认情况,所以会自动包含;但如果你使用它,会更加清晰,因为disable novalidate(取消禁用)实际上是禁用了禁用主键的能力,这里使用了一个可爱的双重否定。 RELY是可选的;它指定在创建视图时是否考虑主键。与rely相反的是norely
创建视图约束有许多限制,而且它依赖于下面的表,正如@RC所指出的那样,这并不值得。但如果你只需要它用作文档,请看这里:
SQL> create table tmp_test ( a number(10), b varchar2(120) );

Table created.

SQL>
SQL> insert into tmp_test
  2   select level, 'b'
  3     from dual
  4  connect by level <= 20
  5          ;

20 rows created.

SQL>  commit ;

Commit complete.

SQL>
SQL> alter table tmp_test
  2    add constraint tmp_test_pk
  3        primary key (a)
  4        using index;

Table altered.

SQL>
SQL> create or replace view v_tmp_test (a, b
  2     , constraint v_tmp_test_pk primary key (a) rely disable novalidate) as
  3   select a, b
  4     from tmp_test
  5          ;

View created.

SQL>

根据文档

视图约束

Oracle不强制执行视图约束。但是,对视图的操作受到基础基表上定义的完整性约束的限制。这意味着您可以通过在基表上的约束来强制实施对视图的约束。

关于视图约束的注释:

您只能在视图上指定唯一、主键和外键约束。但是,您可以使用WITH CHECK OPTION子句定义视图,该子句等效于为视图指定检查约束。

视图约束仅在DISABLE NOVALIDATE模式下受支持。您不能指定任何其他模式。声明视图约束时必须指定DISABLE关键字。无需显式指定NOVALIDATE,因为它是默认值。

RELY和NORELY参数是可选的。通常会使用RELY参数指定视图约束以使其更有用,因为它们未被执行。RELY或NORELY关键字必须在DISABLE关键字之前。请参见“RELY子句”了解更多信息。

由于视图约束不能直接执行,因此您无法指定INITIALLY DEFERRED或DEFERRABLE。

您无法指定using_index_clause、exceptions_clause子句或references_clause的ON DELETE子句。

您不能在对象列的属性上定义视图约束。


这真是救命稻草,我成功地克服了Entity Framework 6的问题,该问题涉及从“union all”生成可空列的视图中获取可空值。我进行了“alter view” -> alter view v_tmp_test add constraint v_tmp_test_pk primary key (a) rely disable novalidate; - sTx

3

您需要将约束条件设置为禁用状态。这实际上是一种向优化器提供提示以影响查询计划的方法。

数据完整性是在底层表级别强制执行的。如果你想一下,强制执行主键约束在视图级别并没有太多意义。一个普通的视图并不存储数据,它只是由其他表提供的数据的“视图”。如果仅在某个基础表的视图上放置了主键约束,并且该表本身不强制执行约束,那么当有人直接使用破坏其约束的数据更新表时,该视图将如何处理?(即表不知道通过视图放置在其上的任何约束)


这只是对我来说文档的问题。 - Andrey Balaguta

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接